Voici un tableau simple où les enregistrements peuvent référencer les enregistrements parents dans le même tableau:
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)
);
Avec l'exigence supplémentaire que l'une des autres valeurs de champ ( num
) doit être identique entre les enregistrements parent et enfant, j'ai pensé qu'une clé étrangère composite devrait faire l'affaire. J'ai changé la dernière ligne en
FOREIGN KEY (parent_id, num) REFERENCES foo(id, num)
et obtenu ERREUR: il n'y a pas de contrainte unique correspondant aux clés données pour la table référencée "foo" .
Je peux facilement ajouter cette contrainte, mais je ne comprends pas pourquoi elle est nécessaire, alors qu'une des colonnes référencées ( id
) est déjà garantie d'être unique? D'après moi, la nouvelle contrainte serait redondante.
NULL != NULL
. Quoi qu'il en soit .. :)UNIQUE INDEX
où sont les colonnesNULLABLE
.. c'est pourquoi je l'ai mentionné. :) Mais je suis d'accord - dans le cas où il n'y a pas de NULL (et pas d'index partiel non plus), c'est probablement assez simple.Les clés étrangères en général (pas seulement composites) DOIVENT pointer vers une CLÉ UNIQUE d'une certaine sorte dans une autre table. Sinon, il n'y aurait pas d'intégrité des données relationnelles.
Cela se plaint car, alors que vous avez une clé unique sur (id) .. vous n'avez PAS de clé unique sur (id, num) .. Ainsi, en ce qui concerne la base de données, la paire (id, num) est pas GARANTI d'être unique. Nous, en tant qu'humains, pouvons comprendre que ce sera unique, mais je suis sûr qu'il y aurait beaucoup de code supplémentaire qu'ils devraient ajouter pour rendre Postgres assez intelligent pour voir que "oh hé .. id est censé être unique , donc id, num doit également être unique "..
Je serais très surpris s'ils ajoutaient ce code lorsque tout ce que vous avez à faire est de créer un autre index unique sur les deux colonnes pour résoudre le problème.
Juste pour être clair, le code qu'ils devraient ajouter ne serait pas seulement ce cas simple ... il devrait gérer tous les cas, même ceux où la clé étrangère est sur 4+ colonnes, etc. Je suis sûr la logique serait assez complexe.
la source