Pular para o conteúdo
Cursos

DevClub

LógicaFront-endBack-endMobile

IA Club

IA na prática
Estudar programaçãoEstudar IA

Aula 2 de 6

Modele PostgreSQL com chaves e restrições

Transforme regras do negócio em chaves primárias, estrangeiras, unicidade, obrigatoriedade e checks que o PostgreSQL consegue garantir.

52 minutos · leitura + prática · nível iniciante

Ao terminar esta aula, você vai conseguir

  • Separar entidades e relações em tabelas coerentes
  • Aplicar primary key, foreign key, unique e check
  • Reproduzir e interpretar uma violação de integridade
Uma tabela relaciona colunas id, nome e cidade em linhas.

Modelagem relacional transforma regras do negócio em tabelas e relações. Nesta aula, você vai representar alunos, cursos e matrículas e fazer o PostgreSQL rejeitar estados impossíveis. O resultado não será apenas um diagrama: serão restrições executáveis e um erro de integridade que você sabe interpretar.

Pense num evento com credenciais. Cada pessoa recebe um número único; a lista de inscrições só pode citar pessoas e oficinas cadastradas; a mesma pessoa não pode ocupar duas vezes a mesma vaga. Primary key, foreign key e unique formalizam regras parecidas. O limite da analogia é que o banco não descobre as regras do evento sozinho. Você precisa expressá-las, e mudanças exigem migração.

Separe entidades sem perder a relação

Alunos e cursos existem por conta própria. Matrícula representa a relação entre os dois. Um modelo inicial é:

sql
CREATE TABLE alunos (
  id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
  nome text NOT NULL,
  email text NOT NULL UNIQUE,
  ativo boolean NOT NULL DEFAULT true
);

CREATE TABLE cursos (
  id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
  titulo text NOT NULL,
  carga_horas integer NOT NULL CHECK (carga_horas > 0)
);

A chave primária identifica uma linha. UNIQUE impede e-mails repetidos. O CHECK exige carga positiva. NOT NULL trata ausência; ele não impede texto vazio. Se '' também for inválido, a aplicação e uma restrição adicional devem representar essa decisão.

Agora crie a tabela de ligação:

sql
CREATE TABLE matriculas (
  id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
  aluno_id bigint NOT NULL REFERENCES alunos(id),
  curso_id bigint NOT NULL REFERENCES cursos(id),
  status text NOT NULL CHECK (status IN ('ativa', 'concluida', 'cancelada')),
  matriculado_em timestamptz NOT NULL DEFAULT now(),
  UNIQUE (aluno_id, curso_id)
);

A chave estrangeira garante que aluno e curso existam. A restrição única composta impede repetir o mesmo par, mas permite que um aluno participe de cursos diferentes e que um curso tenha vários alunos.

Evite guardar na matrícula o nome atual do aluno só para poupar o primeiro join. Essa cópia pode divergir quando o cadastro muda. Dados derivados podem ser úteis em relatórios ou fotografias históricas, mas precisam de uma regra clara de atualização. Comece com uma fonte por fato e introduza duplicação apenas depois de medir a necessidade.

Decida o que acontece na remoção

Sem uma ação explícita, o PostgreSQL normalmente bloqueia a remoção de uma linha que ainda é referenciada. Isso protege o histórico. ON DELETE CASCADE removeria as linhas dependentes; SET NULL preservaria a linha e limparia a referência, desde que a coluna aceite NULL.

Não escolha CASCADE para eliminar uma mensagem incômoda. Pergunte: uma matrícula deve desaparecer quando o curso é removido, ou o curso deveria ser arquivado? Dados históricos geralmente pedem preservação. A ação correta vem do ciclo de vida do negócio.

Reproduza uma violação útil

Com apenas um aluno de ID 1, tente:

sql
INSERT INTO matriculas (aluno_id, curso_id, status)
VALUES (999, 10, 'ativa');

O servidor rejeita a linha porque alunos.id = 999 não existe. Não “resolva” desativando a foreign key. Verifique o identificador recebido e devolva uma mensagem coerente. Outro erro controlado é repetir o mesmo par de aluno e curso; a restrição única deve impedir a duplicata.

O laboratório usa tabelas representadas por JSON e um interpretador de SQL básico no navegador. Ele não aplica chaves, restrições ou joins e não se conecta ao PostgreSQL. Consulte alunos e depois troque para SELECT * FROM matriculas WHERE curso_id = 101;. Espere duas linhas. Esse exercício serve para conhecer os dados; as garantias desta aula precisam ser praticadas num banco isolado.

Sua missão é escrever o modelo, inserir um caso válido e reproduzir duas violações: chave estrangeira ausente e matrícula duplicada. Registre qual regra barrou cada comando. Na próxima aula, vamos operar essas tabelas com CRUD e confirmar cada mudança com saídas observáveis.

Laboratório ao vivo

Inspecione tabelas relacionadas

Consulte alunos ativos e depois matrículas de um curso. O simulador executa SELECT básico em uma tabela por vez; não oferece joins nem PostgreSQL real.

Pronto para testar

Resultado

Pare e pense

Qual é a função de uma chave estrangeira?

Escolha uma resposta
Missão da aula

Faça sem copiar

Modele alunos, cursos e matrículas. Impeça e-mail duplicado, carga negativa e duas matrículas do mesmo aluno no mesmo curso.

Fontes para consultar

Terminou a missão?

Marque apenas quando você conseguir explicar o conceito e concluir o desafio. O progresso fica salvo somente neste navegador.

Próxima: CRUD no PostgreSQL com SQL e RETURNING →