Contraintes dans une base de données relationnelle - Pourquoi ne pas les supprimer complètement?


20

Y a-t-il une raison de créer des contraintes entre les tables (à l'intérieur de SQLserver) de nos jours? Si oui, quand? La plupart des applications dans mon domaine sont construites sur des principes d'objet et les tables sont jointes à la demande. La demande est basée sur le besoin de l'application. Je ne chargerai pas un tas de tables contraintes pour une simple recherche, qui à son tour (après action) nécessite une autre recherche simple.

Les outils ORM tels que EntityContext, Linq2Data, NHibernate gèrent également les contraintes par eux-mêmes, au moins vous savez quelles tables ont besoin les unes des autres. Faire des contraintes à l'intérieur du serveur revient à faire (forcer) les mêmes changements deux fois?

Ce n'est généralement pas une question à décider, mais cette base de données est conçue de manière très différente. La conception semble régulière, reflétant principalement les objets utilisés par les applications. Ce qui me dérange, ce sont toutes les contraintes configurées dans SQLserver avec "not cascade". Ce qui signifie que vous devez jouer "chercher et trouver" lors du codage de nouvelles requêtes de base de données. Certains cas nécessitent jusqu'à 10 niveaux d'une commande exacte pour effectuer une seule suppression.

Cela me surprend et je ne sais pas comment le gérer.

Dans mon monde simple, ce paramètre fait que les contraintes perdent l'essentiel. OK si la base de données était accessible à partir d'hôtes sans connaissance de la conception.

Comment agiriez-vous dans ce scénario?
Pourquoi ne pas simplement supprimer toutes les contraintes de db et les conserver au niveau de l'application?


6
Vous envisagiez de toujours accéder aux données via un seul outil ORM? Ou envisagiez-vous de vous amuser à reproduire correctement toutes les contraintes dans chaque outil ORM utilisé?
Donal Fellows

1
Selon mon dernier commentaire à Peter, je suis d'accord. Le point de relier toutes les contraintes à la base de code (et de les supprimer de db) était très étroit et est probablement pleinement applicable aux applications de courte durée. Probablement aussi pour certains développeurs / projets RAD.
Indépendant

4
Petite erreur: je pense que cela devient un peu déroutant lorsque vous appelez les connexions de clé étrangère entre les tables "relations". Les "relations" dans une base de données relationnelle sont les tables elles-mêmes, pas les connexions. Surtout lorsque nous continuons et parlons de «conception relationnelle» - cela signifie-t-il des tables ou des clés étrangères?
Thomas Padron-McCarthy

Merci. J'appelle les «connexions entre les tables» pour les contraintes. Par conséquent, vous avez probablement raison de voir une "base de données relationnelle" pour les principes de conception de tables (structure des tables). Une description encore plus précise serait «modèle de conception», lorsqu'il s'agit de la base de données «relation versus objet».
Indépendant

1
Votre base de données va survivre à votre code d'application. De plus, votre ORM nuit aux performances de votre application et il y a de fortes chances que vous finissiez par vouloir le contourner au moins dans certains cas d'utilisation. Si vous ne le savez pas maintenant, vous le saurez éventuellement. samsaffron.com/archive/2011/03/30/… . En outre, la suppression de toutes les contraintes laisse votre base de données complètement incapable de protéger sa propre intégrité lorsqu'elle est utilisée abusivement par des applications autres que la vôtre, ce qui pourrait être n'importe quoi d'une autre application réelle à un exécutant dans le couloir avec Excel.
Craig

Réponses:


46

Deux raisons générales de ne pas supprimer les contraintes de DB :

  • Il est possible d'accéder à d'autres applications, maintenant ou à l'avenir , qui peuvent ou non utiliser ORM. Même si les développeurs de ces applications dupliquent fidèlement toutes les contraintes (ce qui peut être beaucoup plus difficile à utiliser avec des solutions non ORM de niveau inférieur), c'est toujours un travail supplémentaire. Et sinon, même une petite omission suffit pour briser l'intégrité du schéma ... ce que vous ne voulez pas risquer. Dans la plupart des entreprises, les données stockées dans leur base de données sont l'élément vital de leur entreprise, leur intégrité doit donc être garantie par tous les moyens. Et le meilleur moyen éprouvé pour y parvenir est d'implémenter autant de contraintes que possible dans la base de données.
  • L'optimiseur de requêtes s'appuie beaucoup sur les contraintes connues au niveau de la base de données. Si vous supprimez les contraintes, les performances des requêtes peuvent commencer à se détériorer . Vous ne le remarquerez peut-être pas immédiatement, mais un jour, il vous frappera et il sera peut-être trop tard pour le réparer facilement. La nature des choses est que les performances de la base de données ont tendance à tomber en panne au moment du pic de charge, lorsqu'il y a le moins de possibilité d'apporter des améliorations de conception soigneuses et bien pensées, soutenues par des mesures de performances exactes et une analyse détaillée pour identifier les causes profondes.

Votre cas concret sonne comme si le schéma de base de données pouvait avoir été initialement généré par un outil ORM (ou conçu par une personne peu expérimentée dans le monde relationnel), il est donc sous-optimal du point de vue relationnel. Il est probablement préférable de l'analyser et de l'améliorer vers une conception relationnelle plus "naturelle", tout en restant cohérente avec les vues ORM. Il peut être utile d'impliquer un expert DB dans cette analyse.


5
@ Jonas, puis parlez au gars des problèmes perçus avec sa conception de base de données. Relationnel et orienté objet sont deux mondes différents - ni l'un ni l'autre n'est une "amélioration" par rapport à l'autre en soi, et les deux ont leur propre place. Concevoir une application C # sur des principes relationnels est une erreur aussi grave que de concevoir une base de données à la manière OO.
Péter Török

3
@Jonas, reflétant vos mises à jour: si vous avez besoin d'écrire des requêtes trop complexes pour réaliser des choses apparemment simples contre le schéma de base de données, c'est soit un signe que la conception de la base de données est inadéquate pour son objectif - soit que vous n'êtes pas suffisamment qualifié (veuillez ne vous offusquez pas, il ne ressort pas clairement de votre post à quel point vous êtes expérimenté avec SQL. En tant que déni de responsabilité, je suis moi-même loin d'être un expert.)
Péter Török

1
J'ai probablement quelques expressions à apprendre, pour me rendre perceptible :). J'ai relu la question et les réponses et je dois inverser. Il y a définitivement un point fort avoir DB comme maître pour toutes les contraintes. Tous les systèmes doivent être conçus à partir de cela. Une vue très étroite pour dire que la base de code ferait le travail. Si chaque système peut avoir sa propre décision concernant les contraintes, cela va se terminer par un chapparral élevé avec de fausses relations suggérées et des tables entières orphelines. Si ce n'est pas maintenant, cela se produit plus tard avec d'autres codeurs.
Indépendant

8
"Il peut être consulté par plus d'applications, maintenant ou dans le futur." Sans parler d'un administrateur de base de données, exécutant des requêtes SQL brutes pour résoudre un problème avec la base de données, pendant que les utilisateurs attendent ...
Thomas Padron-McCarthy

5
+1: si db stocke des données d'entreprise (pas seulement la configuration de l'application, etc.), alors la probabilité que la base de données sorte en direct ou soit étendue en dehors de l'application actuelle approche à 100%
Binary Worrier

27

Les applications peuvent aller et venir, mais les données vivent pour toujours. Dans mon entreprise, la DB a plus de 30 à 40 ans, elle vivra aussi longtemps que l'entreprise existera. Les applications changent, les développeurs vont et viennent. Il vaut mieux avoir l'intégrité et un bon modèle de données logique. De cette façon, quelqu'un peut consulter les données et obtenir une compréhension significative sans avoir à passer par une base de code complexe. Cela permet également de générer des rapports de manière significative. Les applications peuvent également et auront des bogues et la contrainte de base de données est une protection contre cela. Ma position par défaut est d'avoir autant de contraintes (FK et check) que possible.
La seule raison de ne pas avoir de contrainte serait que votre modèle de conception ne le permette pas, par exemple, table par hiérarchie ou problèmes de performances.


Je dirai que vous faites ici un conseil très sage. Mon opinion peut mieux correspondre au développement RAD ou à tout développement où les applications ont une courte durée de vie - Juste pour des raisons de maintenance minimisée pendant le développement.
Indépendant

15

Ce qui me dérange, ce sont toutes les contraintes configurées dans SQLserver avec "not cascade".

Cela ne me dérange pas, cela signifie que quelqu'un a fait preuve de bon sens. Les suppressions en cascade sont souvent très mauvaises pour la base de données. En premier lieu, vous souhaitez parfois que la suppression échoue si vous avez des données dans des tableaux associés. Par exemple, si vous avez un client qui a une commande dans le passé, vous ne voulez pas qu'il soit supprimé ou vous perdez les données sur qui était la commande et une suppression en cascade nous débarrasserait de l'enregistrement qui vous gâcherait les rapports financiers .

Vous semblez penser que la facilité de développement est la chose la plus importante. Dans le monde des bases de données, ce n'est tout simplement pas vrai. L'intégrité des données est la première chose la plus critique suivie de près par les performances et la sécurité des données. S'il faut plus de temps pour écrire les requêtes, alors tant pis.

La base de données est généralement gérée par de nombreuses applications = un ou plusieurs sites Web ou applications de bureau, une application de création de rapports, des services Web, la fenêtre de requête, les processus ETL, etc. Si vous n'appliquez pas de contraintes au niveau de la base de données, vous perdez d'abord l'intégrité des données car l'une de ces applications peut ne pas suivre toutes les règles. Deuxièmement, vous devez coder ces contraintes plusieurs fois et les réécrire si vous décidez d'utiliser une autre application ultérieurement. Troisièmement, vous ne pouvez pas contrôler à l'avance s'il sera nécessaire d'effectuer une sorte de tâche de maintenance des données qui ne se fera pas via l'application (par exemple, corriger les données d'une mauvaise importation de données client ou modifier tous les 10 000 000 d'enregistrements d'un client à un autre client lorsque l'entreprise est achetée par un concurrent). Les développeurs d'applications ne font généralement pas


Merci pour votre réponse. Tous les processus et types d'application dont vous parlez doivent parler à un DAL (qui à son tour contiendrait les contraintes). MAIS! Votre point est parfait et votre commentaire est bon. Sidenote: Oui. J'ai tendance à essayer de faciliter le développement. Pour moi, moins de complexité peut représenter moins de façons de mal faire. Ce n'est pas "vouloir développer plus facilement / plus rapidement", même si cela pourrait l'être - s'il est mal géré. C'est pourquoi je poste cette question! Je verrais aussi quelqu'un de bon sens si cette non-cascade était choisie avec sens, pas à 100% comme dans ce scénario. Je dois trouver des raisons.
Indépendant

@Jonas, il peut également y avoir des raisons de performances. Dépend du nombre d'enregistrements enfants. OK si vous supprimez de petits groupes, mais si des millions d'enregistrements peuvent être déclenchés, vous feriez mieux de faire des lots et de ne pas verrouiller toutes les tables pendant tout le processus. En général, de nombreux dbas n'autorisent pas les suppressions en cascade uniquement pour cette raison, car elles peuvent verrouiller un système de prod si une suppression affecte trop d'enregistrements.
HLGEM

2
Non, tous les processus ne doivent pas parler à un DAL. Les processus ETL ne le font généralement pas, ni les choses qui doivent se produire au niveau de la base de données qui affectent de nombreux enregistrements lorsque des changements importants se produisent (comme le client racheté). Vous ne pouvez pas non plus interdire à quiconque d'utiliser la fenêtre de requête pour effectuer une modification unique. Je n'ai jamais vu une base de données qui n'imposait pas de constraits au niveau de la base de données qui n'avait pas de problèmes d'intégrité au fil du temps.
HLGEM

10

J'ai lu quelque part quelque part qui disait essentiellement: Les données sont la clé de votre application . Si vous n'accéderez JAMAIS aux données via votre interface utilisateur (et je veux dire toujours , comme maintenant et pour toujours, pour toute l'éternité ... ou la durée de vie de votre application, de toute façon), vous n'avez pas besoin de contraintes de base de données. Mais il y a toujours une chance que quelque chose d'autre que l'application elle-même ait besoin de toucher des données, par exemple un service Web, une API publique, une tâche de râteau / un travail SQL / cron / un script automatisé, alors vous vous épargnerez beaucoup d'ennuis potentiels dans le route en gardant les contraintes DB.

Je crois fermement que c'est le seul domaine du développement logiciel où vous ne devriez pas appliquer DRY (et je m'attends à une multitude de votes négatifs pour cette déclaration). Vos données sont le cœur et l'âme de votre application - si jamais elles sont corrompues au-delà de toute réparation, c'est: game over. Cela vaut la peine que l'OMI applique les contraintes partout où elles sont nécessaires. Si cela signifie sous la forme de déclencheurs et de contraintes au niveau de la base de données, de validations côté serveur sur le middleware et de Javascript côté client sur l'interface utilisateur (pour les applications Web), alors c'est l'OMI un mal nécessaire pour garantir que les données sont toujours vierges .


6

Savez-vous ce que signifie ORM? Mappage relationnel-objet. Citant Wikipedia "technique pour convertir des données entre des systèmes de types incompatibles ". Yup, les modèles relationnels et objets ne vont pas ensemble. Les ORM font une assez bonne conversion, en respectant les règles des deux types de systèmes. Les SGBDR sont organisés de telle manière que vous atteignez l'intégrité des données en utilisant des contraintes. En général, l'intégrité est une chose très agréable à avoir, donc les ORM ont tendance à les utiliser lors de la création d'un modèle de données pour stocker des données d'objet. Votre ORM a probablement une bonne raison d'utiliser des contraintes "non en cascade". Et si cela vous oblige à faire des requêtes compliquées au lieu de simplement créer / mettre à jour / supprimer certains objets, alors quelque chose ne va pas avec votre configuration ORM.

Si vous considérez le concept relationnel comme ennuyeux, alors pourquoi n'utilisez-vous pas la base de données d'objets? Il y a quelque temps, ils étaient lents (c'est pourquoi la plupart des gens utilisent encore des SGBDR) mais d'après ce que j'ai entendu, les choses ont un peu changé. Vous vous débarrasseriez de toutes les astuces relationnelles. Objets simplement à l'intérieur, objets à l'extérieur.


Le sujet concerne le retrait de la fonctionnalité de contrainte de la base de données et le recours aux paramètres / au développement dans la base de code (par exemple .net parlant: Entity / Linq2Sql).
Indépendant

Oui, je sais, mais mon point est que vous devez d'abord comprendre pourquoi les contraintes sont là en premier lieu, puis pourquoi ce pourrait être une mauvaise idée de les supprimer.
Jacek Prucia,

Déplacé! Pas abandonné. Je comprends que vous regrettez la connaissance de la qustion, dont il n'était pas question.
Indépendant

Vous ne pouvez pas vraiment déplacer quoi que ce soit entre des systèmes incompatibles. Vous allez supprimer les contraintes de base de données, introduire des contraintes d'application et simplement espérer qu'elles fonctionneront de la même manière (ce qui pourrait s'avérer vrai ou faux). Quoi qu'il en soit, mes sincères excuses si j'ai mal compris votre question.
Jacek Prucia,

Merci! "Bouger" signifie "bouger" littéraire. Cela signifie que vous créez (une bonne expression) des contraintes d'application sur chaque système. Au moins chaque système qui ne peut pas partager le même DAL. Un très bel exemple était les requêtes directes d'un administrateur de base de données qui "réparaient quelque chose". Aucune contrainte de base de données et manque de connaissances en matière de conception peuvent entraîner des données orphelines ou des données totalement faussées.
Indépendant

6

Eh bien, c'est ce qu'a fait eBay et ils ont probablement l'une des plus grandes bases de données au monde:

http://www.dba-oracle.com/oracle_news/news_ebay_massive_oracle.htm http://www.addsimplicity.com/downloads/eBaySDForum2006-11-29.pdf

Malgré ce qui a été dit ci-dessus à propos de l'augmentation des performances par l'intégrité référentielle, elle peut en fait être dégradée; c'est pourquoi des bases de données massives ont abandonné leurs contraintes et fait le travail dans la couche application. Et pour autant que je sache, c'est la seule très bonne raison.

En supprimant ces contraintes, vous perdez essentiellement votre filet de sécurité qui maintient les données propres et qui entraîne ses propres problèmes. Comme pour tout, c'est un équilibre. Je suppose qu'en général, maintenir l'intégrité référentielle est la bonne chose à faire.

Ayant travaillé dans un environnement de développement à forte intégrité référentielle, je sais que du point de vue d'un développeur, cela peut être une douleur totale; souvent dans un environnement de développement, un peu de données sales n'a pas d'importance et trouver comment supprimer une ligne peut prendre une heure ou plus. Cependant, cela peut également être très utile, car les contraintes rendent le schéma explicite.


Enfin quelqu'un qui me comprend :-). Vous avez tout à fait raison, l'équilibre est un très gros point ici. Déplacer les contraintes au niveau de l'application peut être une alternative sûre, si cela se fait comme un point stratégique. Ce serait bien avec certaines URL de sites aux performances avérées dégradées en raison de fortes contraintes / intégrité.
Indépendant

10
Oui et n'oubliez pas - n'oubliez pas - qu'Ebay, comme Facebook et Amazon - est un gazillion fois plus grand que 99,99% des bases de données, et ce qui est bon pour elles est probablement très différent de ce qui est bon pour votre base de données.
Tony Andrews

2
Et ebay, Facebook, Amazon n'utilisent probablement pas de bases de données sans contraintes pour leurs logiciels financiers et comptables ou leurs logiciels d'inventaire ou leurs données RH ou n'importe où où ne pas perdre de données est critique.
HLGEM

2
Si vous avez suffisamment de temps, d'expertise et d'argent, vous pouvez éventuellement programmer n'importe quel SGBDR, serveur Web ou système d'exploitation pour répondre à un besoin spécifique.
JeffO

1
eBay n'a pas fait cela tant que le volume de données auquel ils faisaient face a essentiellement dépassé la capacité des serveurs de bases de données à faire face, et ils ont eu les millions à investir dans leur nouvelle architecture. Si vous effectuez des milliards de transactions par jour, assurez-vous par tous les moyens de supprimer les contraintes et de passer à un système entièrement basé sur des files d'attente, sans transaction et massivement évolutif comme eBay. Sinon, ne sous-estimez pas votre serveur de base de données et ne laissez pas votre base de données sujette à la corruption de données en supprimant toutes vos contraintes.
Craig

4

Premièrement - ma réponse: non, vous ne devez pas vous fier uniquement à l'application pour gérer vos données.

Cela pointe vers un débat plus large: les ORM ont encouragé une culture du dédain pour l'interaction DB "directe", souvent au détriment de la normalisation / intégrité référentielle. Les tableaux sont mappés de force à des hiérarchies d'objets arbitraires, au détriment de la conception implicite dans le modèle relationnel. Le découplage privilégié par OOP est sans doute sacrifié ici car l'application fait sentir sa conception dans la structure des données. Bien que l'ORM ait démontré une grande utilité, il semble être basé sur l'abus ou la méfiance de SQL.

De nouveaux paradigmes font (re) leur apparition, par exemple la programmation fonctionnelle. Si l'équipe de développement décide d'adopter une nouvelle méthodologie de programmation, quelles implications cela aura-t-il pour les données structurées selon les exigences de l'ORM?

Je suis d'accord avec @Jacek Prucia - Je pense que l'ORM est un mauvais match pour le SGBDR, j'opterais personnellement pour un DBAL sur RDBMS, ou opterais pour un OODB avec ORM.


+1 pour parler des alternatives au sujet. L'autre côté du débat est bien sûr: "Quelle serait la gravité de certaines données?" et la réponse peut être l'annulation ou l'insertion d'un milliard d'argent dans un compte bancaire de quelqu'un d'un million de dollars. Ainsi que certaines données orphelines qui sont supprimées avec de bonnes routines de nettoyage. Le résumé de ce sujet ressemble à la cohérence du coût de la flexibilité. Ce qui à son tour dépend entièrement de la gravité du contenu et de l'utilisation de la base de données.
Indépendant

3

Les contraintes sont votre seule garantie de cohérence et d'intégrité des données au niveau de la base de données. Bien sûr, vous pouvez appliquer des contraintes à l'aide de votre code d'application, mais que se passe-t-il si, à l'avenir, vous devez modifier directement les données? Vous pourriez comprendre comment maintenir l'intégrité des données, mais pas quelqu'un d'autre. Garder les contraintes au niveau des données garantit que l'intégrité est assurée même lorsque quelqu'un fait du singe dans des endroits qu'il ne comprend pas.

De plus, disons que votre application doit être réécrite, mais avec la même base de données en place. Toutes ces contraintes dans le code ne demandent que des bogues qui empêchent une entrée tout en permettant le passage de données erronées.

Lors du développement, restez simple. Les contraintes vous le permettent. (Cela dit, lorsqu'une contrainte renvoie une erreur, ne crachez pas la même erreur à l'utilisateur. Rendez l'erreur compréhensible.)

(En ce qui concerne le problème de la cascade: c'est une bonne chose. Je préfère lancer une erreur selon laquelle certains autres enregistrements doivent être supprimés en premier lieu, plutôt que de compter sur la cascade pour que tout soit correct. Les cascades sont agréables en théorie, mais pas nécessairement donc en pratique.)


2

Un problème avec les contraintes dans une base de données est qu'elles donnent au programme des informations limitées sur ce qui a échoué et comment y remédier. Cela signifie que, pour une manipulation en douceur, il est souvent nécessaire de répéter la vérification des contraintes dans l'application, et donc la vérification des contraintes de la base de données est un effort inutile.

Cela risque de compromettre l'intégrité des données, nous avons donc des compromis à faire ici. Pour les données importantes, garantir l'intégrité des données est presque toujours plus important que les performances, et il est préférable de faire échouer une transaction même si elle semble arbitraire que de gâcher les données.

Pour supprimer les contraintes en toute sécurité, il est donc primordial de sécuriser l'accès à la base de données afin que rien ne puisse changer la base de données sans vérifier les contraintes. Ce n'est pas fiable lors de l'écriture de nouvelles applications ou de la mise au point de moyens ad hoc pour gérer les données, car il suffit d'une erreur et la base de données est corrompue.

Par conséquent, pour éviter les contraintes de la base de données, il est nécessaire d'établir à l'avance ce qui peut et ce qui ne peut pas être fait avec la base de données, afin que toutes les applications puissent être écrites, examinées et testées de manière approfondie. Toutes les exigences de base de données doivent être établies à l'avance, et toute modification des exigences de base de données nécessitera un travail considérable. Il s'agit en quelque sorte d'une méthodologie de cascade gelée, qui ne fonctionne que dans des cas très spécifiques. (Concevoir, mettre en œuvre et respecter les exigences, c'est un peu comme marcher sur l'eau. Quelque chose doit d'abord être gelé, et s'il n'est pas assez gelé, les résultats peuvent être désastreux.)

Un cas où cela fonctionne est les applications d'entreprise massives comme PeopleSoft et SAP, où l'application fait déjà pratiquement tout, et il existe des moyens soigneusement définis pour l'étendre. Il existe d'autres possibilités, très rares.

Donc, à moins que vous ne travailliez sur un très grand projet d'entreprise (et je ne voudrais pas) ou que vous puissiez marcher sur de l'eau liquide, laissez ces contraintes dans la base de données.


1
Merci pour votre réponse. Les contraintes seront dans la base de données pour ce projet! Je suis complètement convaincu :). J'aurai également des yeux plus larges lorsque j'en déciderai sur de futurs projets et lors de discussions avec d'autres parties.
Indépendant

1
Considérez également que sans les contraintes, vous laissez le soin au code d'application lui-même de détecter qu'il a foiré. C'est le même code d'application qui a violé la contrainte dans votre exemple, soit dit en passant, la contrainte qui a sauvé votre base de données de l'incohérence ou de la corruption des données. Soit dit en passant, l'utilisation de contraintes ne signifie pas automatiquement une baisse des performances et le fait de ne pas utiliser de contraintes laisse votre base de données exposée de sorte qu'elle ne peut pas se protéger.
Craig
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.