J'ai deux tables dans MySQL database- parent
, child
. J'essaie d'ajouter des références de clé étrangère à ma table enfant en fonction de la table parent. Existe-t-il une différence significative entre ON UPDATE CASCADE
etON DELETE CASCADE
Ma table des parents
CREATE TABLE parent (
id INT NOT NULL,
PRIMARY KEY (id)
) ENGINE=INNODB;
Ma question est la suivante: quelle est la différence entre les requêtes SQL suivantes?
ON DELETE CASCADE
CREATE TABLE child ( id INT, parent_id INT, INDEX par_ind (parent_id), FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE CASCADE ) ENGINE=INNODB;
ON UPDATE CASCADE
CREATE TABLE child ( id INT, parent_id INT, INDEX par_ind (parent_id), FOREIGN KEY (parent_id) REFERENCES parent(id) ON UPDATE CASCADE ) ENGINE=INNODB;
ON UPDATE CASCADE ON DELETE CASCADE
CREATE TABLE child ( id INT, parent_id INT, INDEX par_ind (parent_id), FOREIGN KEY (parent_id) REFERENCES parent(id) ON UPDATE CASCADE ON DELETE CASCADE ) ENGINE=INNODB;
Y a-t-il des erreurs dans les requêtes? Que signifient ces requêtes (1,2 et 3)? Sont-ils les mêmes ???
mysql
innodb
mysql-5.5
foreign-key
Loup solitaire
la source
la source
Réponses:
Un très bon fil sur ce sujet se trouve ici et aussi ici . Le guide définitif pour MySQL est, bien sûr, la documentation, à retrouver ici .
Dans le standard SQL 2003, il existe 5 actions référentielles différentes:
Pour répondre à la question:
CASCADE
ON DELETE CASCADE
signifie que si l'enregistrement parent est supprimé, tous les enregistrements enfants sont également supprimés. Ce n'est pas une bonne idée à mon avis. Vous devez garder une trace de toutes les données qui ont déjà été dans une base de données, bien que cela puisse être fait en utilisantTRIGGER
s. (Cependant, voir la mise en garde dans les commentaires ci-dessous).ON UPDATE CASCADE
Cela signifie que si la clé primaire parent est modifiée, la valeur enfant changera également pour refléter cela. Encore une fois à mon avis, pas une bonne idée. Si vous changezPRIMARY KEY
de façon régulière (ou même pas du tout!), Il y a un problème avec votre conception. Encore une fois, voir les commentaires.ON UPDATE CASCADE ON DELETE CASCADE
signifie que si vousUPDATE
OUDELETE
le parent, le changement est répercuté sur l'enfant. C'est l'équivalent desAND
résultats des deux premières déclarations.RESTREINDRE
RESTRICT
signifie que toute tentative de suppression et / ou de mise à jour du parent échouera. C'est le comportement par défaut dans le cas où une action référentielle n'est pas explicitement spécifiée.PAS D'ACTION
NO ACTION
: Du manuel . Un mot clé de SQL standard. En MySQL, équivalent àRESTRICT
. Le serveur MySQL rejette l'opération de suppression ou de mise à jour de la table parent s'il existe une valeur de clé étrangère liée dans la table référencée. Certains systèmes de base de données ont des contrôles différés et ilNO ACTION
s’agit d’un contrôle différé. Dans MySQL, les contraintes de clé étrangère sont vérifiées immédiatement, doncNO ACTION
est identique àRESTRICT
.SET NULL
SET NULL
- encore du manuel. Supprimez ou mettez à jour la ligne de la table parent et définissez la ou les colonnes de clé étrangère de la table enfant surNULL
. Ce n’est pas la meilleure des idées à mon humble avis, principalement parce qu’il n’ya aucun moyen de «voyager dans le temps» - c’est-à-dire regarder dans les tables enfants et associer des enregistrements àNULL
s avec l’enregistrement parent correspondant -CASCADE
ou utiliserTRIGGER
s pour remplir les tables de journalisation afin de suivre changements (mais, voir les commentaires).DÉFINIR PAR DEFAUT
SET DEFAULT
. Encore une autre partie (potentiellement très utile) du standard SQL que MySQL n’a pas pris la peine de mettre en œuvre! Permet au développeur de spécifier une valeur sur laquelle définir la ou les colonnes de clé étrangère sur un UPDATE ou un DELETE. InnoDB et NDB rejetteront les définitions de table avec uneSET DEFAULT
clause.Comme mentionné ci-dessus, vous devriez passer un peu de temps à regarder la documentation, ici .
la source
Ces deux actions sont à effectuer, respectivement, lorsque l’enregistrement référencé sur la table parent change d’identifiant et lorsqu’il est supprimé.
Si vous exécutez:
Et il y a au moins un enregistrement
child
avecparent_id = 1
, 1) échouera; dans les cas 2) et 3), tous les enregistrements avec parent_id = 1 sont mis à jour pour parent_id = -1.Si vous exécutez:
Et il y a au moins un enregistrement
child
avecparent_id = 1
, 2) échouera; dans les cas 1) et 3), tous les enregistrements avecparent_id = 1
sont supprimés.3) est syntaxiquement correct.
Une documentation complète est disponible sur le manuel .
la source
Je n'ai pas assez de réputation pour commenter les réponses précédentes. Alors j'ai pensé élaborer un peu.
1) ON DELETE CASCADE signifie que si l'enregistrement parent est supprimé, tous les enregistrements enfants référençant sont également supprimés. ON UPDATE a pour valeur RESTRICT, ce qui signifie que UPDATE sur l'enregistrement parent échouera.
2) L'action ON DELETE est définie par défaut sur RESTRICT, ce qui signifie que la suppression de l'enregistrement parent échouera. ON UPDATE CASCADE mettra à jour tous les enregistrements enfants référençant lors de la mise à jour de l'enregistrement parent.
3) Voir les actions CASCADE en 1) et 2) ci-dessus.
Utilisation des ID d’enregistrement parent comme clés étrangères (dans les tables enfants) - l’expérience dit a) si les ID sont des numéros de séquence générés automatiquement, NE les utilisez PAS en tant que clés étrangères. Utilisez plutôt une autre clé parent unique. b) si les ID sont des GUID, vous pouvez les utiliser comme clés étrangères. Vous verrez l'intérêt de cette suggestion lorsque vous exportez et importez les enregistrements ou que vous les copiez dans une autre base de données. Il est trop fastidieux de traiter des numéros de séquence générés automatiquement lors de la migration de données lorsqu'ils sont référencés en tant que clés étrangères.
la source