J'ai remarqué un MATCH SIMPLE
et MATCH FULL
, mais je ne comprends pas ce qu'ils font. Je vois que la valeur par défaut est MATCH SIMPLE
; mais, comment les autres clauses MATCH
aux FOREIGN KEY
fonction de contrainte?
Vérifier la CREATE TABLE
page du manuel :
Il existe trois types de correspondance:
MATCH FULL
,MATCH PARTIAL
, etMATCH SIMPLE
(qui est la valeur par défaut).MATCH FULL
ne permettra pas qu'une colonne d'une clé étrangère multicolonne soit nulle à moins que toutes les colonnes de clé étrangère soient nulles; s'ils sont tous nuls, la ligne n'a pas besoin d'avoir une correspondance dans la table référencée.MATCH SIMPLE
permet à n'importe laquelle des colonnes de clé étrangère d'être nulle; si l'un d'eux est nul, la ligne n'a pas besoin d'avoir une correspondance dans la table référencée.MATCH PARTIAL
n'est pas encore implémenté. (Bien sûr,NOT NULL
des contraintes peuvent être appliquées aux colonnes de référence pour empêcher ces cas de se produire.)
Aussi, dans le chapitre sur les clés étrangères :
Normalement, une ligne de référence n'a pas besoin de satisfaire la contrainte de clé étrangère si l'une de ses colonnes de référence est nulle. Si
MATCH FULL
est ajouté à la déclaration de clé étrangère, une ligne de référence ne s'échappe en satisfaisant la contrainte que si toutes ses colonnes de référence sont nulles (donc un mélange de valeurs nulles et non nulles est garanti d'échouer unMATCH FULL
contrainte). Si vous ne voulez pas que les lignes de référence puissent éviter de satisfaire la contrainte de clé étrangère, déclarez la ou les colonnes de référence commeNOT NULL
.
Et assurez-vous de consulter le manuel actuel ou la version correspondant à votre installation. Ne craignez pas les liens Google obsolètes vers des versions obsolètes.
FULL
vs SIMPLE
vs PARTIAL
Bien que la réponse choisie soit correcte, si cela est nouveau pour vous, vous voudrez peut-être la voir avec du code - je pense qu'il est plus facile de faire comme ça.
-- one row with (1,1)
CREATE TABLE foo ( a int, b int,
PRIMARY KEY (a,b)
);
INSERT INTO foo (a,b) VALUES (1,1);
--
-- two child tables to reference it
--
CREATE TABLE t_full ( a int, b int,
FOREIGN KEY (a,b) REFERENCES foo MATCH FULL
);
CREATE TABLE t_simple ( a int, b int,
FOREIGN KEY (a,b) REFERENCES foo MATCH SIMPLE
);
Logiquement, avec FULL
et SIMPLE
, nous pouvons insérer une correspondance complète.
-- works
INSERT INTO t_full (a,b) VALUES (1,1);
INSERT INTO t_simple (a,b) VALUES (1,1);
Le problème survient lorsque l'une des colonnes est NULL
.
-- works
INSERT INTO t_simple (a,b) VALUES (1,NULL);
-- fails
INSERT INTO t_full (a,b) VALUES (1,NULL);
L'insertion dans t_full
Génère l'erreur suivante,
ERROR: insert or update on table "t_full" violates foreign key constraint "t_full_a_fkey"
DETAIL: MATCH FULL does not allow mixing of null and nonnull key values.
INSERT 0 1
Ok, alors qu'en est-il de (42,NULL)
- c'est la partie que j'ai toujours trouvé confuse à propos de MATCH SIMPLE
,
-- works
INSERT INTO t_simple (a,b) VALUES (42,NULL);
Le comportement ci-dessus ne PAS fonctionnera avec le MATCH PARTIAL
Non implémenté, qui fait probablement ce que vous voulez pour un index composé où se trouve la colonne la plus à droite NULL
ed out. Cependant, certaines personnes considèrent cela comme une méthode d'ouverture d'une boîte de Pandore à une mauvaise conception.
MATCH FULL
Tout doit correspondre entièrement , ou toutes les colonnes doivent être NULL
MATCH SIMPLE
Si une chose est NULL
la contrainte est simplement ignorée.MATCH PARTIAL
Si une chose est NULL
le fait que tout n'est pas NULL
est partiellement récupéré par faire quelque chose de sensé aux fins de la contrainte.Pour la postérité, voici les définitions de la spécification SQL sur le <match type>
MATCH SIMPLE
Si au moins une colonne de référence est nulle, la ligne de la table de référence passe la vérification des contraintes. Si toutes les colonnes de référence ne sont pas nulles, la ligne passe la vérification des contraintes si et seulement s'il existe une ligne de la table référencée qui correspond à toutes les colonnes de référence.MATCH PARTIAL
: Si toutes les colonnes de référence sont nulles, la ligne de la table de référence passe la vérification des contraintes. Si au moins une colonne de référence n'est pas nulle, la ligne passe la vérification des contraintes si et seulement s'il existe une ligne de la table référencée qui correspond à toutes les colonnes de référence non nulles.MATCH FULL
: Si toutes les colonnes de référence sont nulles, la ligne de la table de référence passe la vérification des contraintes. Si toutes les colonnes de référence ne sont pas nulles, la ligne passe la vérification des contraintes si et seulement s'il existe une ligne de la table référencée qui correspond à toutes les colonnes de référence. Si une colonne de référence est nulle et une autre colonne de référence n'est pas nulle, la ligne de la table de référence viole la vérification des contraintes.
Bien que cela ne soit pas spécifique à PostgreSQL, ces exemples sont illustrés avec PostgreSQL