Chaves primárias, estrangeiras e relacionamentos

Chaves dão identidade aos fatos e precisão às conexões
Na aula anterior, vimos que uma relação reúne tuplas sob o mesmo esquema. Falta responder duas perguntas essenciais: como distinguir uma tupla das demais e como afirmar que um valor em uma relação corresponde a uma tupla de outra?
Chaves respondem a essas perguntas. Uma chave candidata identifica um fato sem atributos excedentes. Uma chave primária é a candidata escolhida como identificação principal. Uma chave estrangeira faz valores de uma relação referenciarem uma chave única de outra — ou da própria relação.
Chave não é apenas uma coluna chamada id, nem sinônimo de índice. Ela é uma propriedade lógica do esquema, materializada no banco por restrições.
Superchave identifica, mas pode conter excesso
Considere a relação:
ESTUDANTE(id_estudante, email, nome)
Suponha que id_estudante e email sejam obrigatórios, únicos e estáveis. Cada um identifica sozinho uma tupla. Os conjuntos {id_estudante, nome} e {email, nome} também identificam, porque contêm atributos que já bastam. Todo conjunto de atributos capaz de identificar unicamente uma tupla é uma superchave.
O problema é que uma superchave pode carregar atributos desnecessários. Se id_estudante basta, acrescentar nome não melhora a identidade. Ao contrário: aumenta a chave, espalha um dado mutável por referências e esconde qual atributo realmente garante unicidade.
Chave candidata é uma superchave mínima
Uma chave candidata é uma superchave mínima: se retirarmos qualquer atributo dela, a identificação deixa de ser garantida. No exemplo, {id_estudante} e {email} são candidatas. {id_estudante, nome} não é, pois nome pode ser removido.
Minimalidade não significa o menor número armazenado, o texto mais curto ou a candidata de menor tamanho entre todas. Significa apenas que nenhuma parte daquela chave é excedente.
A chave primária é uma candidata escolhida
Uma relação pode possuir várias chaves candidatas, mas escolhemos no máximo uma como chave primária. As candidatas restantes são chamadas de chaves alternativas e continuam merecendo restrições de unicidade quando representam regras reais do domínio.
No SQL, PRIMARY KEY combina unicidade e proibição de NULL. O PostgreSQL documenta ainda que uma tabela pode ter apenas uma restrição de chave primária, embora possa ter várias restrições UNIQUE.
CREATE TABLE estudante (
id_estudante bigint PRIMARY KEY,
email text NOT NULL UNIQUE,
nome text NOT NULL
);
Nesse esquema, id_estudante é a primária e email é uma candidata alternativa protegida por UNIQUE e NOT NULL. O nome não participa da identidade.
Como escolher entre as candidatas
Uma boa chave primária tende a ser:
- estável: não muda quando o fato evolui;
- mínima: não contém atributo dispensável;
- obrigatória: existe desde a criação do registro;
- inequívoca: sua regra de geração e comparação é clara;
- controlada: não depende de um identificador que outra organização possa reciclar;
- adequada à exposição: não revela dado pessoal ou significado que não deveria circular.
Esses critérios importam mais do que a preferência automática por números ou textos.
Chaves naturais e substitutas podem coexistir
Uma chave natural nasce do domínio: matrícula acadêmica, código oficial ou outro atributo que já identifica o fato no mundo modelado. Uma chave substituta — também chamada de artificial ou surrogate key — é criada somente para identificar, como um inteiro gerado ou UUID.
A chave natural reduz a criação de identificadores sem significado, mas pode ser longa, composta, externa ou mutável. A substituta costuma ser estável e simples de referenciar, porém não protege sozinha as duplicações do negócio.
Considere TRILHA. Usar id_trilha como primária não impede dois registros com o mesmo slug. Se o slug deve ser único, a regra continua necessária:
CREATE TABLE trilha (
id_trilha bigint PRIMARY KEY,
slug text NOT NULL UNIQUE,
titulo text NOT NULL
);
Chave composta precisa de todas as partes
Uma chave composta possui mais de um atributo. Em MODULO, o par (id_trilha, ordem) pode identificar a posição de um módulo dentro de sua trilha:
MODULO(id_modulo, id_trilha, ordem, titulo)
Se cada trilha não pode ter dois módulos na mesma ordem, (id_trilha, ordem) é uma chave candidata composta. ordem isolada não identifica, pois várias trilhas possuem módulo 1. id_trilha isolado também não identifica, pois uma trilha possui vários módulos.
Podemos escolher id_modulo como primária substituta e manter a candidata de negócio:
CREATE TABLE modulo (
id_modulo bigint PRIMARY KEY,
id_trilha bigint NOT NULL,
ordem integer NOT NULL,
titulo text NOT NULL,
UNIQUE (id_trilha, ordem)
);
“Composta” descreve a quantidade de atributos; “candidata”, “primária” e “estrangeira” descrevem papéis. Uma chave pode ser simultaneamente composta e primária, ou composta e estrangeira.
Chave estrangeira declara uma referência válida
Uma chave estrangeira (foreign key, ou FK) é formada por atributos da relação referenciadora cujos valores devem corresponder a uma chave primária ou única da relação referenciada. Ela transforma uma coincidência de valores em uma regra do esquema.
CREATE TABLE modulo (
id_modulo bigint PRIMARY KEY,
id_trilha bigint NOT NULL,
ordem integer NOT NULL,
titulo text NOT NULL,
UNIQUE (id_trilha, ordem),
FOREIGN KEY (id_trilha) REFERENCES trilha (id_trilha)
);
Agora não é válido gravar um módulo com id_trilha = 42 se nenhuma trilha identificada por 42 existir. A FK aponta para valores, não para a posição física de uma linha.
Uma estrangeira não precisa referenciar obrigatoriamente a primária. Ela pode referenciar outra chave declarada única. Em SQL, o número e os tipos das colunas correspondentes precisam ser compatíveis. Se a chave referenciada é composta, a estrangeira também precisa fornecer todas as partes correspondentes.
Quando a participação é opcional, uma FK pode admitir NULL; quando é obrigatória, deve receber NOT NULL. Detalhes sobre referências parcialmente nulas, atualização, exclusão e ações como CASCADE pertencem à próxima aula, sobre integridade.
Relacionamentos aparecem como combinações de chaves
As cardinalidades do modelo entidade-relacionamento orientam onde colocar FKs e quais restrições adicionais declarar.
Um para muitos
Em TRILHA 1:N MODULO, cada módulo referencia uma trilha, enquanto o mesmo id_trilha pode aparecer em vários módulos. A FK fica no lado N.
Um para um
Uma FK comum permite que o mesmo valor referenciado apareça em muitas tuplas; portanto, ela representa N:1. Para limitar a uma tupla, adicionamos UNIQUE à FK. A obrigatoriedade de cada lado depende também de NOT NULL e da posição escolhida para a referência.
Muitos para muitos
Em ESTUDANTE N:N TRILHA, criamos uma relação associativa, como MATRICULA. Ela contém uma FK para cada participante. Se a regra permite apenas uma matrícula do estudante em cada trilha, o par pode ser a primária composta:
CREATE TABLE matricula (
id_estudante bigint REFERENCES estudante (id_estudante),
id_trilha bigint REFERENCES trilha (id_trilha),
matriculada_em date NOT NULL,
PRIMARY KEY (id_estudante, id_trilha)
);
Autorrelacionamentos também usam chaves estrangeiras
Uma tabela pode referenciar a si mesma. Um conteúdo pode possuir outro conteúdo como pré-requisito:
CREATE TABLE conteudo (
id_conteudo bigint PRIMARY KEY,
titulo text NOT NULL,
prerequisito_id bigint,
FOREIGN KEY (prerequisito_id) REFERENCES conteudo (id_conteudo)
);
O papel dos atributos precisa permanecer claro: id_conteudo identifica a tupla atual; prerequisito_id identifica outra tupla que exerce o papel de pré-requisito. A FK garante existência, mas não impede sozinha ciclos como A depender de B e B depender de A. Essa é uma regra adicional do domínio.
Chave estrangeira e JOIN não são sinônimos
Uma FK é uma restrição de integridade: impede referências incompatíveis. JOIN é uma operação de consulta: combina linhas segundo uma condição. É possível executar um JOIN entre colunas sem FK, mas o banco não terá a mesma garantia de que toda referência é válida.
Também é possível declarar uma FK e nunca consultar as tabelas juntas. A restrição continua protegendo inserções e alterações. Os conceitos se complementam, mas têm funções distintas.
Chave e índice também são conceitos diferentes
Chaves pertencem ao modelo lógico e expressam identidade ou referência. Índices são estruturas de acesso voltadas à localização eficiente. Muitos SGBDs criam automaticamente um índice para sustentar PRIMARY KEY e UNIQUE; isso é uma decisão de implementação, não a definição de chave.
No PostgreSQL, declarar uma FK não cria automaticamente um índice nas colunas referenciadoras. Esse índice pode ser útil em consultas e operações de manutenção, mas a decisão depende da carga e será tratada na aula de índices e planos de execução.
Erros comuns ao projetar chaves
- usar qualquer coluna hoje única: a ausência atual de duplicatas não prova uma regra permanente;
- escolher uma superchave com excesso: atributos desnecessários aumentam referências e tornam mudanças mais difíceis;
- criar
ide esquecer a unicidade do negócio: a substituta impede IDs repetidos, não fatos duplicados; - usar dado mutável ou pessoal como primária sem avaliar o ciclo de vida: alterações se propagam e a exposição cresce;
- referenciar uma coluna não única: a referência não teria um destino inequívoco;
- omitir parte de uma chave composta: a correspondência fica incompleta ou ambígua;
- acreditar que FK produz 1:1: sem unicidade no lado referenciador, vários registros podem apontar para o mesmo destino;
- tratar o sufixo
_idcomo garantia: nomes ajudam leitores, mas somente a restrição protege o banco; - confundir FK com JOIN ou índice: integridade, consulta e acesso físico são responsabilidades distintas;
- atribuir significado sequencial ao identificador: uma chave identifica; ela não promete ordem cronológica.
Um roteiro para revisar as chaves
- Escreva o fato que cada tupla representa.
- Liste todos os conjuntos de atributos que o identificam por regra, não por coincidência.
- Remova de cada conjunto os atributos excedentes para encontrar as candidatas.
- Escolha uma primária estável, mínima, obrigatória e controlada.
- Preserve as candidatas alternativas com unicidade e nulabilidade coerentes.
- Declare FKs somente para chaves referenciadas inequívocas.
- Confira todas as partes e a correspondência de uma chave composta.
- Use
UNIQUEna FK quando o relacionamento realmente for 1:1. - Modele N:N por uma relação associativa que represente um fato próprio.
- Separe a decisão lógica de chaves da decisão física de índices.
O que você deve guardar
Superchave é qualquer conjunto que identifica; chave candidata é uma superchave sem atributo excedente. A primária é apenas a candidata escolhida, e as alternativas continuam importantes. Chaves naturais vêm do domínio; substitutas são criadas para identificação e não eliminam restrições únicas do negócio.
Uma chave estrangeira referencia uma chave primária ou única e exige correspondência entre valores compatíveis. FKs comuns representam N:1; uma FK única pode materializar 1:1; duas FKs numa relação associativa representam N:N. Chaves compostas exigem todas as partes necessárias para identificar ou referenciar sem ambiguidade.
Na próxima aula, veremos como a integridade de entidade, a integridade referencial e as regras de negócio determinam o que ocorre quando dados são inseridos, atualizados ou excluídos.
Referências
- Codd, E. F. — A Relational Model of Data for Large Shared Data Banks. Communications of the ACM, 1970. Acesso em 29 ago. 2026.
- ACM, IEEE-CS e AAAI — CS2023: Data Management Core. Acesso em 29 ago. 2026.
- PostgreSQL Global Development Group — Constraints. Acesso em 29 ago. 2026.
- IBM — Primary keys. Acesso em 29 ago. 2026.
- Oracle — Database Concepts. Acesso em 29 ago. 2026.
