Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

Atteint de JavaScriptite Aiguë [Cyril Durand]

Expert ASP.net Ajax et WCF, Cyril Durand parle dans son blog de point techniques sur ASP.net, ASP.net Ajax, JavaScript, WCF et .net en général. Cyril est également consultant indépendant, n'hésitez pas à le contacter pour de l'assistance sur vos projets

Actualités

  • Blog de Cyril DURAND, passionné de JavaScript, Ajax, ASP.net et tout ce qui touche au developpement Web Client-Side.

    N'hésitez pas à me contacter pour vos projets .net : architecture, accompagnement, formation, ...

    View Cyril Durand's profile on LinkedIn
    hit counters


    Expertise Commerce server et BizTalk

Base de données : pour ou contre le on delete cascade / set null

Lorsque l’on conçoit une applicaiton avec une base de données, nous utilisons généralement un modèle de donnée contenant des contraintes d’intégrités, notamment des clés étrangères (foreign key).

La suppression d’un enregistrement peut alors s’averer compliquée puisqu’il faut supprimer, ou mettre une valeur par défaut, toutes les lignes référencées par la ligne que l’on souhaite supprimer. Par exemple, si on souhaite supprimer un utilisateur, il faudra d’abord supprimer ces adresses, etc.

Plusieurs solutions sont possibles :

  • Soit on rajoute un champ IsDeleted permettant d’indiquer l’état de la ligne.
  • Soit on supprime la ligne et toutes les dépendances associés
  • Soit on supprime la ligne et on définit une valeur par défaut sur les lignes référencés

Sous SQL Server, il est possible d’effectuer des actions sur la ligne référencée lorsque l’on supprime un enregistrement : on peut soit supprimer la ligne référencée, soit mettre la valeur par défaut, soit mettre la valeur à null.

image

Ce comportement est surement valable pour d’autres bases de données.

Je travail actuellement avec un modèle composé d’une centaine de tables. A part pour certain cas particulier, je ne souhaite pas conserver l’information, de rajouter un champ “IsDeleted”.

Lorsque je supprime certains enregistrement, plusieurs dizaines de tables peuvent être impactées : effet “boule de neige”. Je me suis alors posé la question de l’utilisation de supprimer en cascade ou mettre certaines valeurs à null. J’utilise Entity Framework et ne souhaite pas utiliser de procédures stockées.

En point positif, j’ai noté :

  • la simplicité d’utilisation par rapport à du code.

En point négatif, j’ai noté :

  • Le risque de supprimer une bonne partie de la base de données en cas de mauvaise configuration
  • Le côté magique : le développeur a moins l’impression de controler ce qu’il se passe au niveau du code.
  • Le déport de logique : la base de donnée decider des actions qu’elle souhaite faire, elle fait plus que ce que le code lui demande.
  • le côté mythe : “c’est comme un trigger : c’est mal“

Je n’ai pas fait de test concernant la différence de performance entre la suppression des relations depuis le code et le on delete cascade.

Au final, j’ai décidé d’utiliser le “on delete” des clés étrangères. Les développeurs ne peuvent pas ajouter eux même ce comportement, seul les responsables du schéma peuvent effectuer ces modifications.

Et vous, qu’en pensez vous ? êtes vous pour ou contre l’utilisation du “on delete” sur les clés étrangères ?

Posted: mardi 3 mai 2011 10:34 par cyril
Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :

Commentaires

richardc a dit :

J'ai eu le cas avec un client qui avait "designé" sa base de données. Il m'a appelé un jour me disant : "VOTRE appli a tout supprimé, j'ai tout perdu !!!" (et il était franchement pas content).

Heureusement, le pb venait de son cascade delete qu'il avait implémenté, lui :P

Je dirais que pour les données critiques, importantes, l'utilisation d'un flag est meilleure, plus secure, et c'est au dbAdmin de faire le ménage de temps en temps, en toute connaissance.

My 2cts

# mai 3, 2011 11:09

Poppyto a dit :

Ca dépend du nombre de tables, là sur une centaine de table ça vaut le coup !

# mai 3, 2011 12:12

Graveen a dit :

Avec un DBA, je privilégie l'approche de Richard.

Sans DBA (cas des applications embarquant une base de donnée fichier ou équivalent (SQLite, Access), je pense qu'il est intéressant que la base de donnée se purge d'elle-même.

Aprés, il y a l'aspect volumétrique qui rentre en compte.

# mai 3, 2011 13:14

christian a dit :

@Poppyto: Une centaine de table à delete en cascade je pense que l'appli a un sacré problème, celà signifie aussi se farcir une jointure sur 100 tables pour lire les données, çà me fait froid dans le dos.

@Cyril : Je rajouterais dans les point négatif que çà utilise le trigger INSTEAD OF de la table pour le DELETE et qu'il n'est plus possible de l'utiliser pour autre chose.

Autant je n'aime pas les options On Cascade autant j'aime bien le set Null ou Set Default ! C'est pratique car on met une veleur particulière en cas de suppression du parent, on garde une trace

@richardc : J'ai souvenir du même problème mais dans Access

# mai 4, 2011 09:21

cyril a dit :

Merci Christian pour tes retours. En terme de performance, cela dit quoi ?

Je ne supprime pas d'informations importantes, de données utilisateur, il s'agit dans la plupart des cas de données applicatifs. Dans l'application sur laquelle je travaille, on peut supprimer un pays, les pays sont liés à plein de choses, des régions qui elles sont liés à des villes qui etc. Lorsque je supprime un pays, je supprime les régions et les villes mais toutes les autres informations relatifs à ces informations (une bonne dizaine de table) je fais un set null ou set default.

# mai 4, 2011 10:30

christian a dit :

En terme de perf çà revient à executer un certain nombre de requête SELECT + DELETE en plus, de toute facon on aurait pu/du le faire à la mano, donc bon...

Ca peut devenir un problème s'il y a un très grand volume de données à traiter car le(s) trigger(s) vont tous traiter dans la même transaction.

Autre point qui me revient on ne peut pas dans SQL Server avoir plus de 32 niveau d'imbrication de code, c'est valable pour les triggers, donc pas plus de 32 tables en chaine sur un cascade !

# mai 4, 2011 11:12
Les commentaires anonymes sont désactivés

Les 10 derniers blogs postés

- Créer un périphérique Windows To Go 10 ! par Blog de Jérémy Jeanson le 11-21-2014, 04:54

- RDV à Genève le 12 décembre pour l’évènement “SharePoint–Office 365 : des pratiques pour une meilleure productivité !” par Le blog de Patrick [MVP Office 365] le 11-19-2014, 10:40

- [IIS] Erreurs web personnalisées par Blog de Jérémy Jeanson le 11-19-2014, 00:00

- BDD/TDD + Javascript par Fathi Bellahcene le 11-16-2014, 16:57

- Sécuriser sans stocker de mots de passe par Blog de Jérémy Jeanson le 11-15-2014, 08:58

- Où télécharger la preview de Visual Studio 2015 ? par Blog de Jérémy Jeanson le 11-13-2014, 21:33

- Les cartes sont partout ! par Le blog de Patrick [MVP Office 365] le 11-13-2014, 17:26

- [ #Office365 ] Courrier basse priorité ! par Le blog de Patrick [MVP Office 365] le 11-12-2014, 08:56

- [Oracle] Fichier oranfsodm12.dll absent du package client par Blog de Jérémy Jeanson le 11-10-2014, 20:44

- [ #Office365 ] Le chapitre 1 des Groupes est écrit, et alors ? par Le blog de Patrick [MVP Office 365] le 11-10-2014, 20:23