En termes de bases de données, est-ce que "normaliser pour l'exactitude, dénormaliser pour la performance" est un bon mantra?
la normalisation conduit à de nombreuses caractéristiques essentielles et souhaitables, y compris le plaisir esthétique. En outre il est aussi théoriquement "correct". Dans ce contexte, la dénormalisation est appliquée comme un compromis, une correction pour atteindre la performance. Est-il une raison autre que les performances d'une base de données pourrait être dénormalisé?
14 réponses
les deux raisons les plus courantes de dénormaliser sont:
- Performance
- Ignorance
le premier doit être vérifié au moyen du profilage, tandis que le second doit être corrigé au moyen d'un journal enroulé; -)
je dirais qu'un meilleur mantra serait "normaliser pour l'exactitude, dénormaliser pour la vitesse - et seulement si nécessaire "
pour bien comprendre l'importance de la question originale, vous devez comprendre quelque chose au sujet de la dynamique d'équipe dans le développement des systèmes, et le genre de comportement (ou mauvais comportement) différents rôles / genres de personnes sont prédisposés. La normalisation est importante parce qu'elle n'est pas seulement un débat sans passion sur les modèles de conception, elle a aussi beaucoup à voir avec la façon dont les systèmes sont conçus et gérés au fil du temps.
base de données les gens sont formés que l'intégrité des données est un question primordiale. Nous aimons penser en termes d'exactitude à 100% des données, de sorte qu'une fois que les données sont dans la base de données, vous n'avez pas à penser ou à traiter avec elle n'a jamais été logiquement faux. Cette école de pensée accorde une grande valeur à la normalisation, car elle force une équipe à s'attaquer à la logique sous-jacente des données et du système. À considérer un exemple trivial -- les clients ont un seul nom et l'adresse, ou pourrait-il avoir plusieurs? Quelqu'un doit décider, et le système va venir cela dépend de l'application uniforme de cette règle. Cela ressemble à une question simple, mais multipliez cette question par 500x pendant que vous concevez un système raisonnablement complexe et vous verrez le problème -- les règles ne peuvent pas simplement exister sur le papier, elles doivent être appliquées. Une conception de base de données bien normalisée (avec l'aide supplémentaire des contraintes d'unicité, des clés étrangères, des valeurs de vérification, des déclencheurs de mise en application logique, etc.) peut vous aider à avoir un modèle de données de base bien défini et des règles d'exactitude des données, ce qui est vraiment important si vous voulez que le système fonctionne comme prévu lorsque de nombreuses personnes travaillent sur différentes parties du système (différentes applications, rapports, etc.) et que différentes personnes travaillent sur le système au fil du temps. Ou pour le dire autrement -- si vous n'avez aucun moyen de définir et d'appliquer opérationnellement un modèle de données de base solide, votre système sera nul.
D'autres personnes (souvent des développeurs moins expérimentés) ne le voient pas de cette façon. Ils voient la base de données comme un outil asservis à la application ils développent, ou au pire une bureaucratie à éviter. (Notez que je parle de développeurs "moins expérimentés". Un bon développeur aura la même conscience de la nécessité d'un modèle de données solide et de l'exactitude des données qu'une personne de base de données. Ils peuvent différer sur ce qui est la meilleure façon d'atteindre cela, mais dans mon expérience sont raisonnablement ouverts à faire ces choses dans une couche de base de données aussi longtemps que L'équipe de base de données sait ce qu'ils font et peut être sensible aux développeurs). Ces moins les gens expérimentés sont souvent ceux qui poussent pour la dénormalisation, comme plus ou moins une excuse pour faire un travail rapide et sale de conception et de gestion du modèle de données. C'est ainsi que vous obtenez des tables de base de données qui sont 1:1 avec des écrans d'application et des rapports, chacun reflétant les hypothèses de conception d'un développeur différent, et un manque complet de santé mentale / cohérence entre les tables. J'ai vécu cela plusieurs fois dans ma carrière. C'est une façon décourageante et profondément improductive de développer système.
ainsi, une des raisons pour lesquelles les gens ont un fort sentiment au sujet de la normalisation est que la question est une stand-in pour d'autres questions sur lesquelles ils se sentent fortement. Si vous êtes entraîné dans un débat sur la normalisation, pensez à la motivation (non technique) sous-jacente que les parties peuvent apporter au débat.
cela dit, Voici une réponse plus directe à la question initiale:)
Il est utile de penser à votre base de données il s'agit d'une conception de base qui se rapproche le plus possible d'une conception logique -- hautement normalisée et limitée -- et d'une conception étendue qui aborde d'autres questions comme les interfaces d'application stables et le rendement.
vous devriez vouloir limiter et normaliser votre modèle de données de base, parce que ne pas le faire compromet l'intégrité fondamentale des données et toutes les règles / hypothèses sur lesquelles votre système est construit. Si tu laisses ces problèmes t'échapper, ton système peut devenir merdique assez vite. Testez votre modèle de données de base par rapport aux exigences et aux données réelles, et itérez comme mad jusqu'à ce qu'il fonctionne. Cette étape ressemblera beaucoup plus à clarifier les exigences qu'à élaborer une solution, et elle devrait le faire. Utilisez le modèle de données de base comme une fonction de forçage pour obtenir des réponses claires sur ces questions de conception pour toutes les personnes impliquées.
complétez votre modèle de données de base avant de passer au modèle de données étendu. Utilisez-le et voyez jusqu'où vous pouvez obtenir avec elle. En fonction de la quantité de données, du nombre d'utilisateurs et des modes d'utilisation, vous n'aurez peut-être jamais besoin d'un modèle de données étendu. Voyez jusqu'où vous pouvez aller avec l'indexation plus les 1 001 boutons liés à la performance que vous pouvez tourner dans votre SGBD.
si vous exploitez vraiment les capacités de gestion de la performance de votre SGBD, alors vous devez envisager d'étendre votre modèle de données d'une manière qui ajoute la dénormalisation. Notez qu'il ne s'agit pas de dénormaliser votre modèle de données de base, mais plutôt ajout de nouvelles ressources qui traitent les données denorm. Par exemple, s'il y a quelques requêtes énormes qui écrasent votre performance, vous pourriez vouloir ajouter quelques tables qui précalculent les données que ces requêtes produiraient -- essentiellement pré-exécution de la requête. Il est important de le faire de manière à maintenir la cohérence des données dénormalisées avec les données de base (normalisées). Par exemple, dans les SGBD qui les supportent, vous pouvez utiliser une vue matérialisée pour faire la maintenance des données denorm automatique. Si votre SGBD n'a pas cette option, alors peut-être que vous pouvez le faire en créant des déclencheurs sur les tables où les données sous-jacentes existent.
il y a un monde de différence entre de façon" sélective dénormaliser une base de données d'une manière cohérente pour faire face à un défi de performance réaliste par rapport au simple fait d'avoir une conception de données faible et en utilisant la performance comme une justification pour cela.
quand je travaille avec des personnes expérimentées et des développeurs de bases de données, j'insiste sur le fait qu'ils produisent un design absolument normalisé ... par la suite, un petit nombre de personnes plus expérimentées pourront participer à une discussion sur la dénormalisation sélective. La dénormalisation est plus ou moins toujours mauvaise dans votre modèle de données de base. En dehors du noyau, il n'y a rien de mal à dénormaliser si vous le faites d'une manière réfléchie et cohérente.
en d'autres termes, dénormaliser d'un modèle normal à une qui préserve le normal tout en ajoutant du dénormal -- qui traite la réalité physique de vos données tout en préservant sa logique essentielle -- est très bien. Les conceptions qui n'ont pas un noyau de conception normale -- qui ne devraient même pas être appelées hors norme, parce qu'elles n'ont jamais été normalisées en premier lieu, parce qu'elles n'ont jamais été consciemment conçues d'une manière disciplinée -- ne sont pas bonnes.
n'acceptez pas la terminologie selon laquelle un design faible et indiscipliné est "anormale" de la conception. Je crois que la confusion entre les données dénormalisées intentionnellement / avec soin par rapport à la conception simple vieille base de données merdique qui résulte en données dénormales parce que le concepteur était un idiot négligent est la cause profonde de beaucoup de débats sur la dénormalisation.
dénormalisation signifie normalement une certaine amélioration de l'efficacité de récupération (sinon, pourquoi le faire à tous), mais à un coût énorme dans la complexité de valider les données au cours des opérations de modification (insérer, mettre à jour, parfois même supprimer). La plupart du temps, la complexité supplémentaire est ignorée (parce qu'il est trop difficile de le décrire), conduisant à des données fausses dans la base de données, qui est souvent pas détecté avant plus tard - comme lorsque quelqu'un essaie de comprendre pourquoi l'entreprise a fait faillite et il s'avère les données étaient incohérentes parce qu'elles étaient dénormalisées.
je pense que le mantra devrait aller "normaliser pour la justesse, dénormaliser seulement lorsque la haute direction offre de donner votre travail à quelqu'un d'autre", à ce moment-là, vous devriez accepter l'occasion d'aller à des pâturages nouveaux puisque l'emploi actuel peut ne pas survivre aussi longtemps que vous le souhaitez.
ou " dénormaliser seulement quand la direction vous envoie un email qui vous exonère pour le désordre qui sera créé."
bien sûr, cela suppose que vous êtes confiant de vos capacités et de la valeur pour l'entreprise.
les Mantras simplifient presque toujours trop leur sujet. C'est un cas au point.
les avantages de la normalisation sont plus que purement théoriques ou esthétiques. Pour chaque départ d'un formulaire normal pour 2NF et au-delà, il y a une anomalie de mise à jour qui se produit lorsque vous ne suivez pas le formulaire normal et qui disparaît lorsque vous suivez le formulaire normal. Départ de 1FN est une toute autre boîte de pandore, et je ne vais pas traiter ici.
ces anomalies de mise à jour consistent généralement en l'insertion de nouvelles données, la mise à jour de données existantes et la suppression de lignes. Vous pouvez généralement contourner ces anomalies par une programmation intelligente et délicate. La question est alors a l'avantage de l'utilisation habile, rusé programmation vaut le coût. Parfois, le prix à payer est les insectes. Parfois, le coût est une perte d'adaptabilité. Parfois, le coût est en fait, croyez-le ou pas, les mauvaises performances.
si vous apprenez les différents formulaires normaux, vous devriez considérer votre apprentissage incomplet jusqu'à ce que vous compreniez l'anomalie de mise à jour d'accompagnement.
le problème avec" dénormaliser " comme ligne directrice est qu'il ne vous dit pas quoi faire. Il ya des myriades de façons d'éliminer une base de données. La plupart d'entre eux sont malheureux, et cela le met charitablement. Une des façons les plus stupides est simplement de dénormaliser une étape à la fois, chaque fois que vous voulez accélérer une requête particulière. Tu te retrouves avec un Mish fou mosh qui ne peut être compris sans connaître l'historique de l'application.
beaucoup de pas dénormalisants qui "semblaient être une bonne idée à l'époque" s'avèrent plus tard être de très mauvais mouvements.
Voici une meilleure alternative, quand vous décidez de ne pas complètement normaliser: adopter une certaine discipline de conception qui donne certains avantages, même lorsque cette discipline de conception s'écarte de la normalisation complète. À titre d'exemple, il y a la conception de schéma d'étoile, largement utilisé dans data warehousing et data marts. Il s'agit d'une approche beaucoup plus cohérente et disciplinée que la simple dénormalisation par caprice. Il y a des avantages spécifiques que vous obtiendrez d'une conception de schéma d'étoile, et vous pouvez les comparer avec les anomalies de mise à jour que vous souffrirez parce que la conception de schéma d'étoile contredit la conception normalisée.
en général, beaucoup de gens qui conçoivent des schémas stellaires construisent une base de données secondaire, Une qui n'interagit pas avec les programmes D'application OLTP. L'un des problèmes les plus difficiles pour maintenir une telle base de données à jour est ce qu'on appelle le traitement ETL (Extract, Transform, and Load). La bonne nouvelle est que tout ce traitement peut être collecté dans une poignée de programmes, et les programmeurs d'application qui traitent avec la base de données normalisée OLTP n'ont pas à apprendre ce genre de choses. Il y a des outils là-bas pour aider avec ETL, et copier des données d'une base de données OLTP normalisée à un mart de données de schéma d'étoile ou un entrepôt est un cas bien compris.
une fois que vous avez construit un schéma d'étoile, et si vous avez bien choisi vos dimensions, nommé vos colonnes sagement, et surtout choisi votre granularité bien, en utilisant ce schéma d'étoile avec des outils OLAP comme Cognos ou objets D'Affaires s'avère être presque aussi facile que de jouer à un jeu vidéo. Cela permet à votre analystes de données pour se concentrer sur l'analyse des données au lieu d'apprendre comment le conteneur de données fonctionne.
il y a d'autres conceptions en dehors du schéma d'étoile qui partent de la normalisation, mais le schéma d'étoile vaut une mention spéciale.
les entrepôts de données dans un modèle dimensionnel sont souvent modélisés dans un schéma d'étoile (dénormalisé). Ces types de schémas ne sont pas (normalement) utilisés pour la production en ligne ou les systèmes transactionnels.
la raison sous-jacente est la performance, mais le modèle fact / dimensional permet également un certain nombre de caractéristiques temporelles comme les dimensions changeant lentement qui sont réalisables dans les modèles ER-style traditionnels, mais peut être incroyablement complexe et lent (dates d'entrée en vigueur, les tables d'archivage, les enregistrements actifs, etc).
n'oubliez pas que chaque fois que vous dénormalisez une partie de votre base de données, votre capacité à l'adapter diminue, au fur et à mesure que les risques de bogues dans le code augmentent, ce qui rend l'ensemble du système de moins en moins durable.
bonne chance!
normalisation de base de données n'est pas seulement pour l'exactitude théorique, il peut aider à prévenir la corruption de données. Je ne dénormaliserais certainement pas pour "simplicité" comme @aSkywalker suggère. Réparer et nettoyer les données corrompues est tout sauf simple.
la normalisation n'a rien à voir avec la performance. Je ne peux pas vraiment le mettre mieux que Erwin Smout l'a fait dans ce fil: Quel est l'impact sur les ressources de normalisation d'une base de données?
la plupart des DBMSs SQL ont un support limité pour changer la représentation physique des données sans compromettre également le modèle logique, donc malheureusement c'est une raison pour laquelle vous pouvez trouver nécessaire de démormaliser. Un autre est que beaucoup de DBMSs n'ont pas bon prise en charge des contraintes d'intégrité multi-tables, afin de contourner la mise en œuvre de ces contraintes, vous pouvez être forcé de mettre des attributs étrangers dans certaines tables.
vous ne normalisez pas pour "l'exactitude" en soi. Voici la chose:
table dénormalisée a l'avantage d'augmenter la performance, mais nécessite une redondance et plus de puissance de cerveau développeur.
tables normalisées a l'avantage de réduire la redondance et d'augmenter la facilité de développement, mais nécessite des performances.
c'est presque comme une équation équilibrée classique. Donc, en fonction de vos besoins (comme combien marteler votre serveur de base de données) vous devriez coller avec des tables normalisées à moins qu'il ne soit vraiment nécessaire. Il est cependant plus facile et moins coûteux de passer d'un développement normalisé à un développement dénormalisé que l'inverse.
pas question. Gardez à l'esprit que ce que vous êtes censé normaliser est vos relations (niveau logique), pas vos tables (niveau physique).
les données dénormalisées sont beaucoup plus souvent trouvées à des endroits où la normalisation a été insuffisante.
mon mantra est "normaliser pour l'exactitude, éliminer pour la performance". Les RDBMs sont des outils très flexibles, mais optimisés pour la situation OLTP. Remplacer le SGBDR par quelque chose de plus simple (par exemple des objets en mémoire avec un journal des transactions) peut aider beaucoup.
je conteste l'affirmation des gens ici que les bases de données normalisées sont toujours associées à du code plus simple, plus propre et plus robuste. Il est certainement vrai qu'il existe de nombreux cas où la normalisation complète est associée à un code plus simple que le code partiellement dénormalisé, mais au mieux c'est une ligne directrice, pas une loi de la physique.
Quelqu'un l'a déjà défini un mot comme la peau d'une idée vivante. Dans CS, vous pourriez dire qu'un objet ou une table est défini en termes de les besoins du problème et de l'infrastructure existante, au lieu d'être platonicien, la réflexion d'un objet idéal. En théorie, il n'y aura pas de différence entre la théorie et la pratique, mais en pratique, vous trouverez des variations par rapport à la théorie. Ce dicton est particulièrement intéressant pour CS parce que l'un des axes du domaine est de trouver ces différences et de les traiter de la meilleure façon possible.
prendre une pause du côté DB des choses et en regardant le côté codant de nombreuses choses, la programmation orientée objet nous a sauvés de beaucoup de maux de spaghetti-codage, en regroupant beaucoup de code étroitement lié ensemble sous un nom de classe objet qui a un sens anglais qui est facile à se rappeler et qui correspond en quelque sorte avec tout le code qu'il est associé avec. Si trop d'information est regroupée, alors vous finissez avec de grandes quantités de complexité à l'intérieur de chaque objet et cela rappelle le code spaghetti. Si vous faites les grappes à petit, alors vous ne peut pas suivre les fils de la logique sans chercher à travers un grand nombre d'objets avec très peu d'information dans chaque objet, qui a été appelé "Code Macaroni".
si vous regardez le compromis entre la taille idéale de l'objet du côté de la programmation des choses et la taille de l'objet qui résulte de la normalisation de votre base de données, je vais donner un clin d'œil à ceux qui diraient qu'il est souvent préférable de choisir sur la base de la base de données et puis de travailler autour de ce choix de code. Surtout parce que vous avez la capacité dans certains cas de créer des objets à partir de jointures avec hibernation et des technologies comme cela. Toutefois, je m'arrêterai loin de dire qu'il s'agit d'une règle absolue. N'importe quelle couche OR-Mapping est écrite avec l'idée de simplifier les cas les plus complexes, peut-être au détriment d'ajouter de la complexité aux cas les plus simples. Et rappelez-vous que la complexité n'est pas mesurée en unités de taille, mais plutôt en unités de complexité. Il y a toutes sortes de systèmes différents y. Certains devraient atteindre quelques milliers de lignes de code et y rester pour toujours. D'autres sont censés être le portail central vers les données d'une entreprise et pourraient théoriquement croître dans n'importe quelle direction sans contrainte. Certaines applications gèrent des données qui sont lues des millions de fois pour chaque mise à jour. D'autres gèrent des données qui ne sont lues qu'à des fins de vérification et à des fins ponctuelles. En général, les règles sont les suivantes:
-
la Normalisation est presque toujours une bonne idée des applications de taille moyenne ou plus grandes lorsque les données des deux côtés de la séparation peuvent être modifiées et que les modifications potentielles sont indépendantes l'une de l'autre.
-
il est généralement plus simple de mettre à jour ou de sélectionner une table que de travailler avec plusieurs tables, mais avec une table ou, cette différence peut être minimisée pour une grande partie de l'espace du modèle de données. Travailler avec le SQL droit, c'est presque trivial de travailler autour d'un cas d'utilisation individuelle, bien qu'elle ne soit pas orientée vers l'objet.
-
le Code doit être relativement réduit à gérer et un moyen efficace de le faire est de diviser le modèle de données et de construire une architecture orientée services autour de différentes pièces du modèle de données. L'objectif d'un état optimal de normalisation des données (de)doit être envisagé dans le cadre du paradigme de votre stratégie globale de gestion de la complexité.
Dans les hiérarchies d'objets complexes, il y a des complexités que vous ne voyez pas du côté de la base de données, comme la cascade des mises à jour. Si vous modélisez des clés étrangères relationnelles et des liens croisés avec une relation de propriété d'un objet, alors lors de la mise à jour de l'objet, vous devez décider s'il faut faire une cascade de la mise à jour ou non. Cela peut être plus complexe qu'en sql à cause de la différence entre faire quelque chose une fois et faire quelque chose correctement toujours, un peu comme la différence entre charger une donnée fichier et écrire un analyseur syntaxique pour ce type de fichier. Le code qui fait passer en cascade une mise à jour ou une suppression en C++, en java, ou tout ce qui est nécessaire pour prendre la décision correctement pour une variété de scénarios différents, et les conséquences des erreurs dans cette logique peuvent être assez graves. Il reste à prouver que cela ne peut jamais être simplifié avec un peu de flexibilité sur le côté SQL assez pour rendre les complexités sql valables.
il y a aussi un point qui mérite d'être délimité avec un de la normalisation des préceptes. Un argument central pour la normalisation dans les bases de données est l'idée que la duplication des données est toujours mauvaise. Cela est souvent vrai, mais ne peut pas être suivi servilement, surtout quand il ya des propriétaires différents pour les différentes pièces d'une solution. J'ai vu une situation une fois dans laquelle un groupe de développeurs a géré un certain type de transactions, et un autre groupe de développeurs a soutenu la vérifiabilité de ces transactions, de sorte que le deuxième groupe de développeurs a écrit un service qui supprimait plusieurs tables chaque fois qu'une transaction se produisait et créait un enregistrement snapshot dénormalisé indiquant, en fait, quel était l'état du système au moment de la transaction. Ce scénario constitue un cas d'utilisation intéressant (du moins pour la partie de la question portant sur la duplication des données), mais il fait en fait partie d'une catégorie plus vaste de questions. Les désirs de conservation des données imposeront souvent certaines contraintes à la structure des données dans la base de données, contraintes qui peuvent entraîner des erreurs dans le traitement et le traitement des données. dépannage plus simple en rendant certains des cas incorrects impossible. Toutefois, cela peut aussi avoir pour effet de "geler" des parties de données, car le fait de modifier ce sous-ensemble de données aurait pour effet d'invalider des opérations passées en vertu des règles de cohérence. Il est évident qu'une sorte de système de versioning est nécessaire pour régler ce problème, donc la question évidente est de savoir s'il faut utiliser un système de versioning normalisé (temps d'efficacité et d'expiration) ou une approche basée sur un instantané (valeur en fonction de la transaction temps.) Il y a plusieurs questions de structure interne pour la version normalisée dont vous n'avez pas à vous soucier avec l'approche snapshot, comme:
- est-ce que les requêtes de plage de dates peuvent être effectuées efficacement même pour les grandes tables?
- Est-il possible de garantir la non-chevauchement de plages de dates?
- est-il possible de retracer les événements de statut jusqu'à l'opérateur, la transaction ou la raison du changement? (oui, probablement, mais c'est frais généraux supplémentaires)
- en créant un système de version plus compliqué, mettez-vous les propriétaires des droits en charge des bonnes données?
je pense que le but optimal ici est d'apprendre non seulement ce qui est correct en théorie, mais pourquoi il est correct, et quelles sont les conséquences des violations, alors quand vous êtes dans le monde réel, vous pouvez décider quelles conséquences valent la peine de prendre pour gagner quels autres avantages. C'est le véritable défi de la conception.
le système de déclaration et le système de transaction ont des exigences différentes.
je recommande pour le système de transaction, toujours utiliser la normalisation pour l'exactitude des données.
pour le système de rapport, utiliser la normalisation à moins que la dénormalisation soit nécessaire pour une raison quelconque, telle que la facilité d'interrogation adhoc, la performance, etc.
simplicité? Je ne suis pas sûr que Steven va me frapper avec son journal, mais là où je traîne, parfois les tables dénormalisées aident les gars qui font le reportage/la lecture seulement à faire leur travail sans déranger la base de données/les développeurs tout le temps...