Quand / Pourquoi utiliser la cascade dans SQL Server?

lors de la configuration des clés étrangères dans SQL Server, dans quelles circonstances devrait-il y avoir une cascade sur delete ou update, et quel est le raisonnement derrière cela?

cela s'applique probablement aussi à d'autres bases de données.

je cherche surtout des exemples concrets de chaque scénario, de préférence de quelqu'un qui les a utilisés avec succès.

129
demandé sur Vinko Vrsalovic 2008-09-12 19:27:36

15 réponses

résumé de ce que j'ai vu jusqu'à présent:

  • certaines personnes n'aiment pas la cascade du tout.

Cascade Supprimer

  • Cascade Supprimer peut avoir un sens lorsque la sémantique de la relation peut impliquer une exclusive "fait partie de " description. Par exemple, un enregistrement OrderLine fait partie de son ordre parent, et les OrderLines ne seront jamais partagées entre plusieurs ordres. Si L'ordre venait à disparaître, L'OrderLine devrait aussi, et une ligne sans ordre serait un problème.
  • l'exemple canonique de suppression en Cascade est SomeObject et Someobjectems, où il n'est pas logique qu'un enregistrement d'items existe sans un enregistrement principal correspondant.
  • Vous devriez pas utiliser les Supprimer en Cascade si vous êtes à la préservation de l'histoire ou à l'aide d'un "soft/suppression logique" où vous définissez uniquement supprimé peu colonne 1/vrai.

Mettre À Jour En Cascade

  • la mise à jour en Cascade peut avoir du sens lorsque vous utilisez une vraie clé plutôt qu'une clé de remplacement (colonne identité/auto-identification) à travers les tableaux.
  • l'exemple canonique pour la mise à jour en Cascade est lorsque vous avez une clé étrangère mutable, comme un nom d'utilisateur qui peut être modifié.
  • Vous devriez pas utiliser la mise à Jour en Cascade, avec des touches qui sont Identité/incrémentation automatique des colonnes.
  • mise à jour en Cascade est mieux utilisé en conjonction avec une contrainte unique.

Quand Utiliser La Cascade

  • vous pouvez vouloir obtenir une confirmation supplémentaire forte de l'utilisateur avant de permettre une opération en cascade, mais cela dépend de votre application.
  • cascade peut vous causer des problèmes si vous configurez mal vos clés étrangères. Mais vous devriez être bien si vous le faites à droite.
  • il n'est pas sage d'utiliser la cascade avant de bien la comprendre. Toutefois, il s'agit d'une caractéristique utile qui mérite qu'on s'y attarde.
113
répondu Joel Coehoorn 2015-05-12 03:35:37
Les clés étrangères

sont le meilleur moyen d'assurer l'intégrité référentielle d'une base de données. Éviter les cascades à cause de la magie c'est comme écrire tout dans assembly parce que vous ne faites pas confiance à la magie derrière les compilateurs.

ce qui est mauvais, c'est l'utilisation incorrecte des clés étrangères, comme les créer à l'envers, par exemple.

L'exemple de Juan Manuel est l'exemple canonique, si vous utilisez le code, il y a beaucoup plus de chances de laisser des Documentems parasites dans le base de données qui va venir et vous mordre.

mises à jour en cascade sont utiles, par exemple, lorsque vous avez des références aux données par quelque chose qui peut changer, disons qu'une clé primaire d'une table utilisateurs est le nom,la combinaison lastname. Alors vous voulez que les changements dans cette combinaison se propagent là où ils sont référencés.

@Aidan, cette clarté dont vous parlez vient à un coût élevé, la chance de laisser des données fausses dans votre base de données, qui est pas petit . Pour moi, c'est généralement un manque de familiarité avec le DB et l'incapacité de trouver les FK qui sont en place avant de travailler avec le DB qui favorisent cette peur. Soit cela, soit un usage abusif constant de cascade, en l'utilisant là où les entités n'étaient pas liées conceptuellement, ou là où vous devez préserver l'histoire.

62
répondu Vinko Vrsalovic 2008-09-14 01:37:44

Je n'utilise jamais de deletes en cascade.

si je veux que quelque chose soit retiré de la base de données, je veux dire explicitement à la base de données ce que je veux retirer.

bien sûr, ils sont une fonction disponible dans la base de données et il peut y avoir des moments où il est bon de les utiliser, par exemple si vous avez une table 'order' et une table 'orderItem' vous pouvez vouloir effacer les éléments lorsque vous supprimez une commande.

j'aime la clarté que je reçois de le faire en code (ou procédure stockée) plutôt que par "magie".

pour la même raison que je ne suis pas non plus un fan des détonateurs.

il faut noter que si vous supprimez un 'ordre', vous obtiendrez un rapport '1 rangée affectée' même si la suppression en cascade a supprimé des orderItem de 50'.

16
répondu Loofer 2008-09-12 15:36:12

je travaille beaucoup avec les suppressions en cascade.

il se sent bien de savoir que quiconque travaille contre la base de données pourrait ne jamais laisser de données indésirables. Si les dépendances grandissent, je change simplement les contraintes dans le diagramme de Management Studio et je n'ai pas à modifier sp ou dataacces.

cela dit, j'ai 1 problème avec les suppressions en cascade et c'est des références circulaires. Cela conduit souvent à des parties de la base de données qui n'ont pas les suppressions en cascade.

12
répondu Mathias F 2008-10-25 16:07:29

un exemple est lorsque vous avez des dépendances entre entités... c'est à dire: Document -> DocumentItems (lorsque vous supprimez un Document, DocumentItems n'avez pas de raison d'exister)

9
répondu juan 2008-09-12 15:33:29

je fais beaucoup de travail de base de données et je trouve rarement la suppression en cascade utile. La seule fois où je les ai utilisés efficacement est dans une base de données de rapports qui est mis à jour par un travail de nuit. Je m'assure que toutes les données modifiées sont importées correctement en supprimant tous les enregistrements de haut niveau qui ont changé depuis la dernière importation, puis réimporter les enregistrements modifiés et tout ce qui s'y rapporte. Cela m'évite d'avoir à écrire beaucoup de suppressions compliquées qui regardent du bas vers le haut de mon la base de données.

Je ne considère pas que les deletes en cascade sont aussi mauvaises que les triggers car ils suppriment seulement des données, les triggers peuvent avoir toutes sortes de choses désagréables à l'intérieur.

en général, j'évite complètement les suppressions réelles et j'utilise les suppressions logiques (c.-à-d. avoir une colonne bit appelée isDeleted qui est définie à true) à la place.

9
répondu Martynnw 2008-09-12 15:51:59

utilisez la suppression en cascade où vous voudriez que l'enregistrement avec le FK soit supprimé si son enregistrement PK référent était supprimé. En d'autres termes, lorsque le dossier est vide de sens sans le référencement d'enregistrement.

je trouve que la suppression en cascade est utile pour s'assurer que les références mortes sont supprimées par défaut plutôt que de causer des exceptions nulles.

5
répondu testpattern 2013-03-01 11:19:08

sur Supprimer Cascade:

lorsque vous voulez supprimer les lignes dans la table enfant si la ligne correspondante est supprimée dans la table parent.

si sur cascade supprimer n'est pas utilisé alors une erreur sera soulevée pour intégrité référentielle .

ON UPDATE Cascade:

quand vous voulez changement de la clé primaire à mettre à jour en clé étrangère

4
répondu Durai Amuthan.H 2014-01-12 16:03:45

l'une des raisons de mettre une suppression en cascade (plutôt que de le faire dans le code) est d'améliorer les performances.

Case 1: avec une cascade supprimer

 DELETE FROM table WHERE SomeDate < 7 years ago;

cas 2: sans cascade supprimer

 FOR EACH R IN (SELECT FROM table WHERE SomeDate < 7 years ago) LOOP
   DELETE FROM ChildTable WHERE tableId = R.tableId;
   DELETE FROM table WHERE tableId = R.tableid;
   /* More child tables here */
 NEXT

Deuxièmement, lorsque vous ajoutez une table enfant supplémentaire avec une suppression en cascade, le code dans le cas 1 continue de fonctionner.

je mettrais seulement dans une cascade où la sémantique de la relation est partie de." Sinon un idiot supprimera la moitié de votre base de données quand vous le faites:

DELETE FROM CURRENCY WHERE CurrencyCode = 'USD'
3
répondu WW. 2010-05-27 20:47:28

j'essaie d'éviter les suppressions ou mises à jour que je n'ai pas explicitement demandées dans SQL server.

soit par cascade, soit par l'utilisation de déclencheurs. Ils ont tendance à vous mordre le cul un certain temps dans la ligne, soit en essayant de traquer un bogue ou en diagnostiquant des problèmes de performance.

où je les utiliserais est en garantissant la cohérence pour peu d'efforts. Pour obtenir le même effet, vous devez utiliser des procédures stockées.

2
répondu pauliephonic 2008-09-12 15:34:38

je, comme tout le monde ici, trouve que les suppressions en cascade ne sont vraiment que marginalement utiles (ce n'est pas vraiment beaucoup de travail pour supprimer des données référencées dans d'autres tables -- s'il y a beaucoup de tables, vous automatisez simplement cela avec un script) mais vraiment ennuyeux quand quelqu'un accidentellement supprime des données importantes qui est difficile à restaurer.

le seul cas où je l'utiliserais est si les données dans la table de tableau est fortement contrôlée (par exemple, limitée permissions) et seulement mis à jour ou supprimé par un processus contrôlé (comme une mise à jour du logiciel) qui a été vérifié.

2
répondu Jen A 2008-09-16 19:05:36

j'ai entendu des Administrateurs de bases de données et/ou la "Société Politique", qui interdisent à l'aide de "on Delete Cascade" (et d'autres) simplement à cause des mauvaises expériences dans le passé. Dans un cas, un gars a écrit trois détonateurs qui ont fini par s'appeler l'un l'autre. Trois jours pour récupérer ont abouti à une interdiction totale des déclencheurs, tout cela à cause des actions d'un idjit.

bien sûr, il faut parfois des déclencheurs au lieu de" ON Delete cascade", comme lorsque certaines données enfant doivent être préservées. Mais dans d'autres cas, son parfaitement valide pour utiliser la méthode ON Delete cascade. Un avantage clé de "ON Delete cascade" est qu'il capture tous les enfants; une procédure écrite de déclenchement/stockage peut ne pas si elle n'est pas codée correctement.

je pense que le développeur devrait être autorisé à prendre la décision basée sur ce qu'est le développement et ce que la spécification dit. Une interdiction du tapis basée sur une mauvaise expérience ne devrait pas être le critère; le processus de pensée "ne jamais utiliser" est draconien au mieux. Un jugement d'appel doit être faite à chaque fois, et les changements apportés par le modèle d'affaires des changements.

n'est-ce pas ce dont il s'agit?

2
répondu BrianBurkill 2018-07-04 00:33:43

une suppression ou une mise à jour de S qui supprime une valeur de clé étrangère trouvée dans certains tuples de R peut être traitée de l'une des trois façons suivantes:

  1. rejet
  2. Propagation
  3. de la négation.

la Propagation est appelée cascade.

il y a deux cas:

‣ Si un tuple de S a été supprimé, supprimer les tuples de R qui lui est soumise.

si un tuple dans S a été mis à jour, mettez à jour la valeur dans les tuples R qui s'y réfèrent.

1
répondu Mayank Chopra 2016-01-25 00:40:48

si vous travaillez sur un système avec de nombreux modules différents dans des versions différentes, il peut être très utile, si les éléments supprimés en cascade font partie de / propriété du support PK. Autrement, tous les modules auraient besoin de correctifs immédiats pour nettoyer leurs articles dépendants avant de supprimer le propriétaire de la clé publique, ou la relation clé étrangère serait omise complètement, laissant peut-être des tonnes de déchets dans le système Si le nettoyage n'est pas effectué correctement.

je viens de vous présenter cascade Supprimer pour une nouvelle table d'intersection entre deux tables déjà existantes (l'intersection à supprimer seulement), après cascade supprimer avait été découragé depuis un certain temps. Ce n'est pas mal non plus si data se perd.

il est, cependant, une mauvaise chose sur enum-comme les tables de liste: quelqu'un supprime l'entrée 13 - jaune de la table" couleurs", et tous les éléments jaunes dans la base de données sont supprimés. En outre, ceux-ci sont parfois mis à jour dans un delete-all-insert-manière, conduisant à référentiel intégrité totalement omise. Bien sûr, c'est faux, mais comment allez-vous changer un logiciel complexe qui fonctionne depuis de nombreuses années, avec l'introduction d'une véritable intégrité référentielle étant à risque d'effets secondaires inattendus?

un autre problème réside dans le fait que les valeurs originales des clés étrangères doivent être conservées même après suppression de la clé primaire. On peut créer une colonne tombstone et une option ON DELETE SET NULL pour le FK original, mais cela nécessite encore des triggers ou du code spécifique pour maintenir la valeur clé redondante (sauf suppression de PK).

0
répondu Erik Hart 2014-08-05 20:21:04
Les suppressions en Cascade

sont extrêmement utiles pour implémenter des entités logiques de super-type et de sous-type dans une base de données physique.

lorsque des tables séparées de super-type et de sous-type sont utilisées pour mettre en œuvre physiquement les super-types/sous-types (au lieu de regrouper tous les attributs de sous-type dans une seule table de super-type physique), il y a une relation un-à-un entre ces tables et la question devient alors comment garder les clés primaires 100% dans la synchronisation entre ces table.

les suppressions en Cascade peut être un outil très utile pour:

1) Assurez-vous que la suppression d'un enregistrement de super-type supprime également l'enregistrement de sous-type correspondant.

2) Assurez-vous que toute suppression d'un enregistrement de sous-type supprime également l'enregistrement de super-type. Ceci est réalisé en mettant en place un" au lieu de " delete trigger sur la table des sous-types qui va et supprime l'enregistrement de super-type correspondant, qui, à son tour, cascade supprime l'enregistrement de sous-type.

en utilisant les suppressions en cascade de cette manière garantit qu'aucun enregistrement de super-type ou de sous-type orphelin n'existe jamais, que vous supprimiez l'enregistrement de super-type en premier ou l'enregistrement de sous-type en premier.

0
répondu Mark Allen 2016-12-09 20:51:35