web-dev-qa-db-fra.com

MySQL sur la cascade de suppression. Exemple de test

Je me pose des questions sur cette question test. J'ai préparé l'exemple moi-même et l'ai testé, mais je ne suis toujours pas sûr de la réponse.

Avec ce qui suit:

CREATE TABLE foo (
  id INT PRIMARY KEY AUTO_INCREMENT, 
  name INT
)

CREATE TABLE foo2 (
  id INT PRIMARY KEY AUTO_INCREMENT, 
  foo_id INT REFERENCES foo(id) ON DELETE CASCADE
)

Pour autant que je puisse voir, la réponse est:

a. Deux tables sont créées

Bien qu'il existe également:

b. Si une ligne de la table foo2, avec un foo_id de 2 est supprimée, alors la ligne avec id = 2 dans la table foo est automatiquement supprimée

d.Si une ligne avec id = 2 dans la table foo est supprimée, toutes les lignes avec foo_id = 2 dans la table foo2 sont supprimées

Dans mon exemple, j'aurais utilisé la syntaxe de suppression:

DELETE FROM foo WHERE id = 2;
DELETE FROM foo2 WHERE foo_id = 2;

Pour une raison quelconque, je n'ai pas pu trouver de relation entre les tables bien qu'il semble qu'il devrait y en avoir une. Il y a peut-être un paramètre MySQL ou peut-être ON DELETE CASCADE pas utilisé correctement dans les requêtes de création de table? Je me demande encore ...

24
Eae

Réponse d. est correct, si et seulement si le moteur de stockage prend réellement en charge et applique les contraintes de clé étrangère.

Si les tables sont créées avec Engine=MyISAM, puis ni b. ou d. est correct.

Si les tables sont créées avec Engine=InnoDB, puis ré. est correct.

REMARQUE:

Cela est vrai pour InnoDB si et seulement si FOREIGN_KEY_CHECKS = 1; si FOREIGN_KEY_CHECKS = 0, puis un DELETE de la table parent (foo) pas supprimera les lignes de la table enfant (foo2) qui référencent une ligne supprimée de la table parent.

Vérifiez cela avec la sortie de SHOW VARIABLES LIKE 'foreign_key_checks' (1 = ON, 0 = OFF) (La valeur par défaut normale est que ce soit ON.)

La sortie de SHOW CREATE TABLE foo montrera quel moteur la table utilise.

La sortie de SHOW VARIABLES LIKE 'storage_engine' affichera le moteur par défaut utilisé lorsqu'une table est créée et que le moteur n'est pas spécifié.

37
spencer7593

Vous avez une relation entre deux tables, c'est dans la commande de création foo2: ... foo_id int references foo(id) on delete cascade.

Selon la référence MySQL Foreign Key Constraints :

CASCADE: supprimez ou mettez à jour la ligne de la table parent et supprimez ou mettez à jour automatiquement les lignes correspondantes dans la table enfant. ON DELETE CASCADE et ON UPDATE CASCADE sont pris en charge.

En outre, selon la référence des clés étrangères MySQL :

Pour les moteurs de stockage autres que InnoDB, il est possible lors de la définition d'une colonne d'utiliser une clause REFERENCES tbl_name (col_name), qui n'a aucun effet réel et ne sert que de mémo ou de commentaire qui vous la colonne que vous définissez actuellement est destinée à faire référence à une colonne d'un autre tableau .

Ainsi, puisque la clé étrangère va de la table enfant à la table parent, elle fait de foo une table parent et foo2 une table enfant, donc la suppression d'une ligne de foo entraînera les suppressions en cascade vers foo2, à condition que vous utilisiez InnoDB ou un autre moteur de stockage qui le prend en charge.

14
Vic