Y a-t-il un moment où nous devrions éviter la suppression en cascade?

11

Dans SQL Server 2008, il existe une table principale qui est liée à trois autres tables enfants par une relation 1 à plusieurs. Nous pensons donc à utiliser la suppression en cascade dans la table principale, afin que tous les enregistrements de la table enfant soient supprimés lorsque l'enregistrement de la table principale est supprimé.

  1. Donc, la suppression en cascade est-elle un bon choix ici?
  2. Quand ne pas utiliser le detele en cascade?
Ramesh
la source
3
Personne ne peut y répondre sans connaître votre cas d'utilisation. La suppression en cascade présente toujours un risque de suppression facile des données. En gros je l'utilise très rarement, dans les cas où c'est le comportement souhaité. Ce sont généralement des tableaux fortement modifiés.
dezso

Réponses:

17

Je me méfie généralement des suppressions en cascade (et d'autres actions automatiques qui pourraient supprimer / endommager les données), via des déclencheurs ou ON <something> CASCADE. Ces installations sont très puissantes, mais aussi potentiellement dangereuses.

  • Donc, la suppression en cascade est-elle un bon choix ici?

Il ferait certainement ce que vous recherchez: supprimer les enregistrements associés lorsqu'un enregistrement parent est supprimé, sans que vous ayez besoin d'implémenter une autre logique pour vous assurer que les enfants sont supprimés en premier, ce qui rend votre code plus concis. Toutes les actions seront enveloppées dans une transaction implicite, donc si quelque chose bloque, l'enfant supprime toute l'opération est bloquée, maintenant l'intégrité référentielle avec peu ou pas d'effort de codage supplémentaire.

Assurez-vous que votre utilisation des suppressions en cascade et autres actions "en coulisses" est bien documentée afin que les futurs responsables du système en soient pleinement conscients.

  • Quand ne pas utiliser le detele en cascade?

Il ne faut pas l'utiliser si vous êtes paranoïaque comme moi! Un point clé à considérer est les autres développeurs qui travaillent actuellement ou pourraient travailler sur votre code / base de données (d'où le commentaire ci-dessus sur la documentation de tout comportement "caché").

Il est assez courant dans mon expérience que des personnes inexpérimentées les utilisent DELETEpuis les ré- INSERTmettent à jour afin de mettre à jour les lignes, surtout quand elles veulent vraiment une opération MERGE/ UPSERT(mettre à jour les lignes existantes et en créer de nouvelles là où une ligne avec une clé donnée n'existe pas) et le SGBD ne prend pas en charge la fusion / upsert (ou ils ne connaissent pas son support). Sans actions en cascade, cela est parfaitement sûr (ou entraînera une erreur lorsqu'il menace l'intégrité des données), mais si quelqu'un le fait pour les lignes d'une table parent où les FK de référence ontON DELETE CASCADEdéfinir alors les données liées seront supprimées à la suite de la suppression initiale et non remplacées - donc les données sont perdues (pas que même si la suppression et l'insertion subséquente sont enveloppées dans des transactions explicites, la cascade se produit avec l'opération de suppression - elle ne le sera pas attendez de voir si la transaction remplace les lignes de la table parent dans les instructions suivantes) et la cascade pourrait continuer à travers d'autres navires de relation (par exemple: supprimer un superviseur principal, son équipe est supprimée par cascade, les équipes de ses équipes sont supprimées par cascade, tous les enregistrements suivis pour toutes ces personnes sont supprimés par cascade, ...). Sans la mise en cascade activée, vous obtiendriez simplement une erreur ici au lieu de perdre les données en silence.

David Spillett
la source
Y aura-t-il des implications en termes de performances? Comme acquérir un verrou et supprimer manuellement serait-il préférable à une cascade?
Ramesh
Je suppose qu'il y aurait très peu de différence, en supposant que le processus plus manuel soit enveloppé dans une transaction explicite que vous devriez faire pour des raisons de cohérence. Les méthodes manuelles et automatiques (en cascade) seront affectées par les niveaux de verrouillage et d'isolement une fois que la concurrence sera prise en compte, bien sûr.
David Spillett
4

Je suppose que la réponse se résume à savoir si oui ou non est logique pour votre situation, cela dépend . Pour votre situation, est-il logique que les lignes de la table «enfant» restent si leurs lignes «principales» correspondantes disparaissent? Les données de la table enfant n'auraient-elles aucun sens sans le parent? Si c'est le cas, la suppression en cascade imposerait l'intégrité référentielle. Vous voudrez peut-être conserver les lignes enfants en tant qu'enregistrement, une archive de l'activité passée (bien que vous puissiez potentiellement écrire ces lignes dans une autre table spécialement à cet effet).

Un exemple que j'utilise pour illustrer ce point est la relation médecin / patient. Un doc peut avoir plusieurs patients. Un patient ne peut être un patient , si elles ont un médecin. Si le doc s'en va (quitte la pratique), alors quelque chose doit arriver aux patients restants. Une possibilité est qu'ils soient purgés. Un autre est qu'une valeur par défaut remplace la référence du document ou elles pourraient être supprimées de la table principale et placées ailleurs. Alternativement, aucune activité ne se produit et les patients restent tels quels, intacts, comme si le doc était toujours présent. Cela dépend de ce que vous voulez faire.

D'après votre expérience personnelle, réfléchissez bien à la conception de la base de données. Cette semaine, j'ai dû exécuter une purge de documents orphelins dans une table qui ne pointait nulle part et occupait littéralement de l'espace.

the_good_pony
la source
Je dois supprimer les enregistrements enfants lorsque l'enregistrement parent disparaît.
Ramesh
Si les enregistrements doivent disparaître complètement et qu'ils n'ont pas de sens à conserver, alors une suppression en cascade aurait plus de sens dans votre situation
the_good_pony
3

L'utilisation de la suppression en cascade est une question de préférence personnelle, comme le fait de nommer ou non des tables avec plusieurs noms (Client vs Clients).

Je préférerais ne jamais utiliser la suppression en cascade. Certaines conceptions de bases de données évitent de supprimer du tout. Il existe peu de justifications pour supprimer des données d'une base de données lorsque l'espace disque est si bon marché. Certaines conceptions de base de données définissent un champ supplémentaire "IsDeleted" plutôt que de supprimer physiquement les données.

Si vous devez supprimer des données, l'utilisation des procédures stockées pour gérer cela vous donne plus de transparence et de contrôle. Votre application peut exécuter une procédure stockée qui supprime l'enfant puis le parent. Vous ne savez pas comment les exigences commerciales évolueront avec le temps, les sp vous offriront ainsi plus de polyvalence. C'est mon 2c.

sa555
la source
Certes, cela vous donne plus de polyvalence, mais il introduit également un comportement "caché", ce qui signifie que vous devez avoir une documentation supplémentaire pour ces sps (afin que ppl sache quelle action commerciale nécessite quel sp) une autre façon pourrait être de restreindre les utilisateurs sql à être uniquement capable d'exécuter ces sps et de ne pas exécuter d'autres insertions / mises à jour "simples" du tout.
DrCopyPaste