web-dev-qa-db-fra.com

Pourquoi utiliser des clés étrangères sans action sur la suppression ou la mise à jour

J'ai une question d'intérêt:

J'ai 2 tables dans mysql avec InnoDb.
table tbl_a possède une clé primaire, nommée a_id;
table tbl_b a un primaire b_id et une clé étrangère sur tbl_a.a_id avec "ON DELETE NO ACTION ".

+-------------+---------------+---------------+
|  Table Name |  Primary Key  |  Foreign Key  |
+-------------+---------------+---------------+
|    tbl_a    |     a_id      |               |
|    tbl_b    |     b_id      |     a_id      |
+-------------+---------------+---------------+

pourquoi devrais-je toujours utiliser InnoDb et des clés étrangères, si je n'utilise pas vraiment la magie des clés étrangères à la fin de toute façon?
Est-il encore utile d'utiliser
innodb et clés étrangères
au lieu de
myisam et aucune clé étrangère .
Si je fais juste "NO ACTION "sur les suppressions ou les mises à jour?

J'espère que vous avez obtenu mon point d'intérêt :)

21
Preexo

Je pense que vous ne comprenez pas ce que ON DELETE NO ACTION veux dire. Cela ne signifie pas de supprimer la contrainte de clé étrangère.

Lorsque vous supprimez un enregistrement auquel une clé étrangère fait référence, InnoDB a la possibilité de prendre une action automatique pour corriger la situation:

  • il peut CASCADE, ce qui signifie, supprimer l'enregistrement référent. (Cela aurait du sens pour quelque chose comme user_address.user_id. Si vous supprimez définitivement un utilisateur, vous souhaiterez probablement également supprimer toutes les adresses de l'utilisateur.)
  • ça peut SET NULL, ce qui signifie, effacez la clé de référence. (Cela pourrait avoir du sens pour quelque chose comme file.last_modified_by. Si vous supprimez définitivement un utilisateur, vous souhaiterez peut-être que la dernière modification du fichier devienne simplement "inconnue".)

Si vous spécifiez NO ACTION, vous dites à InnoDB que vous ne voulez pas qu'il prenne l'une de ces actions. InnoDB ne peut donc pas régler la situation pour vous; tout ce qu'il peut faire, c'est rejeter le DELETE et retourner une erreur.

Par conséquent, ON DELETE NO ACTION est en fait identique à ON DELETE RESTRICT (le défaut).

(Remarque: dans certains SGBD et dans SQL standard, ON DELETE NO ACTION est un peu différent de ON DELETE RESTRICT: dans ceux-ci, ON DELETE NO ACTION signifie "accepter le DELETE dans la transaction en cours, mais rejeter la transaction entière si j'essaye de la valider avant de corriger le problème". Mais InnoDB ne prend pas en charge les vérifications différées, il traite donc ON DELETE NO ACTION exactement la même que ON DELETE RESTRICT, et rejette toujours le DELETE immédiatement .)

Voir §§ 14.2.2.5 "Contraintes FOREIGN KEY" et 13.1.17.2 "Utiliser les contraintes FOREIGN KEY" dans le Manuel de référence MySQL 5.6.

63
ruakh

La contrainte de clé étrangère même sans ON DELETE / UPDATE CASCADE garantit que si vous insérez une valeur dans la table enfant, elle a une valeur correspondant correctement dans la table parent (ou est NULL si la colonne FK est nullable). Toute tentative d'insertion d'une valeur non valide dans la colonne FK de la table enfant entraînerait une erreur en cas d'échec de la contrainte, de sorte que l'intégrité de vos données est protégée.

ERREUR 1452 (23000): impossible d'ajouter ou de mettre à jour une ligne enfant: une contrainte de clé étrangère échoue

La définition de la contrainte de clé étrangère définit également implicitement un index sur la colonne FK dans la table enfant, qui, bien que vous ayez pu définir manuellement l'index, améliorera les performances de jointure.

ON DELETE NO ACTION (ce qui revient à omettre le ON DELETE clause) active empêche la suppression d'une ligne parent si elle est référencée par une table enfant, ne permet pas de la supprimer passivement sans affecter les lignes enfants.

9
Michael Berkowski