Chaves primárias/estrangeiras e normalização
O mecanismo que garante que uma referência entre tabelas nunca aponte pro vazio.
Chave primária (PRIMARY KEY) — o identificador único de cada linha
CREATE TABLE usuarios (
id SERIAL PRIMARY KEY, -- gera 1, 2, 3... sozinho, nunca repete
nome VARCHAR(255)
);Chave estrangeira (FOREIGN KEY) — a garantia de que a referência existe
CREATE TABLE pedidos (
id SERIAL PRIMARY KEY,
usuario_id INTEGER REFERENCES usuarios(id), -- FOREIGN KEY
total DECIMAL
);
INSERT INTO pedidos (usuario_id, total) VALUES (999, 50.00);
-- Error: insert or update on table "pedidos" violates foreign key constraint
-- (não existe usuário com id 999 — o banco RECUSA o dado inconsistente)Sem FOREIGN KEY, nada impede um pedidos.usuario_id apontar pra um usuário que não existe (ou que foi deletado depois) — um "registro órfão". Com a chave estrangeira, o próprio banco garante essa integridade, recusando o insert/update que quebraria a referência.
ON DELETE — o que fazer quando o "pai" é removido
CREATE TABLE pedidos (
id SERIAL PRIMARY KEY,
usuario_id INTEGER REFERENCES usuarios(id) ON DELETE CASCADE,
total DECIMAL
);
-- CASCADE: deletar um usuário deleta automaticamente todos os pedidos dele
-- (a alternativa RESTRICT bloquearia o delete do usuário enquanto ele tiver pedido)Normalização — o motivo de separar em várias tabelas
não-normalizado — dado duplicado e sujeito a inconsistência
pedido_id | cliente_nome | cliente_email | produto
----------|--------------|--------------------|---------
1 | Ana | ana@exemplo.com | Teclado
2 | Ana | ana@exemplo.com | Mouse
-- se o e-mail da Ana mudar, precisa atualizar em CADA linha onde ela aparecenormalizado — cada fato mora em um lugar só
usuarios: id, nome, email
pedidos: id, usuario_id
itens_pedido: pedido_id, produto_id
-- o e-mail da Ana existe em UMA linha só, referenciada por todo o restoNormalizar tem um custo: consultas precisam de mais JOINs pra reconstruir a informação completa. Na prática, a maioria dos sistemas normaliza o suficiente pra evitar duplicação de dado que muda com frequência (nome, e-mail, preço), aceitando o custo do JOIN em troca de consistência.
Exercício
Por que ON DELETE CASCADE pode ser perigoso numa tabela de pedidos, mesmo sendo conveniente?