Aqui está uma tabela simples onde os registros podem fazer referência a registros pai na mesma tabela:
CREATE TABLE foo (
id SERIAL PRIMARY KEY,
parent_id INT NULL,
num INT NOT NULL,
txt TEXT NULL,
FOREIGN KEY (parent_id) REFERENCES foo(id)
);
Com o requisito adicionado de que um dos outros valores de campo ( num
) deve ser idêntico entre os registros pai e filho, pensei que uma chave estrangeira composta deveria funcionar. Eu mudei a última linha para
FOREIGN KEY (parent_id, num) REFERENCES foo(id, num)
e obtive ERRO: não há nenhuma restrição exclusiva correspondente às chaves fornecidas para a tabela referenciada "foo" .
Posso facilmente adicionar essa restrição, mas não entendo por que é necessário, quando uma das colunas referenciadas ( id
) já é garantida como única? A meu ver, a nova restrição seria redundante.
É uma limitação do DBMS - em todos eles até onde eu sei. E não apenas ao adicionar uma coluna, mas também ao reorganizar as colunas. Se tivermos uma
UNIQUE
restrição em(a1, a2)
, não podemos adicionar umFOREIGN KEY
thatREFERENCES (a2, a1)
a menos que haja uma restrição única em that(a2, a1)
que seja essencialmente redundante.Não seria terrivelmente difícil adicionar isso como um recurso:
ou a generalização:
Parece que não foi solicitado ou não foi considerado prioridade alta o suficiente para ser implementado.
Pode sempre solicitar - no respetivo canal - a implementação da funcionalidade. Ou até mesmo implementá-lo você mesmo, se o DBMS for de código aberto, como o Postgres.
Chaves estrangeiras em geral (não apenas compostas) DEVEM apontar para uma CHAVE ÚNICA de algum tipo em outra tabela. Se não o fizessem, não haveria integridade de dados relacionais.
Isso é uma reclamação porque, embora você tenha uma chave exclusiva em (id) .. você NÃO tem uma chave exclusiva em (id, num).. Assim, no que diz respeito ao banco de dados, o par (id, num) é não é GARANTIDO que seja único. Nós, como humanos, podemos descobrir que será único, mas tenho certeza de que haveria muito código adicional que eles teriam que adicionar para tornar o Postgres inteligente o suficiente para ver que "oh, ei ... o id deve ser único , então id,num também deve ser único" ..
Eu ficaria muito surpreso se eles adicionassem esse código quando tudo o que você precisa fazer é criar outro índice exclusivo nas duas colunas para corrigir o problema.
Só para esclarecer, o código que eles teriam que adicionar não seria apenas este caso simples ... teria que lidar com todos os casos, mesmo aqueles em que a chave estrangeira está em mais de 4 colunas, etc. a lógica seria bastante complexa.