48 votes

Quand dénormaliser une conception de base de données

Je sais que normalis(z)ation a été largement discuté sur un Débordement de Pile. J'ai lu beaucoup de discussions antérieures. J'ai quelques questions supplémentaires si.

Je suis en train de travailler sur un système d'héritage avec au moins 100 tables. La base de données est a quelques des nations unies normalisés en fonction de la structure, des tableaux qui contiennent une variété de données disparates, et d'autres problèmes. J'ai été donné la tâche d'essayer de l'améliorer. Je ne peux pas commencer à nouveau, mais besoin de modifier le schéma existant.

Dans le passé, j'ai toujours essayé de conception de bases de données normalisé. Maintenant, les questions. Un développeur senior a suggéré que, dans certains cas, nous ne pouvons normaliser:

1) Avec les données temporelles. Par exemple, une facture est créée que des liens vers d'un produit. Si un client demande une copie de cette facture, un an plus tard, nous devons être en mesure de produire une copie exacte de l'original. Que faire si le prix du produit, le nom ou la description ont été mises à jour? Les seniors gars ont suggéré que le prix du produit et d'autres informations doivent être copiées dans la table de facture. Je pense peut-être que nous devrions avoir une autre table comme productPrice qui a un champ de date afin que nous puissions suivre les changements de prix au fil du temps. Il nous faudrait la même chose pour la description du produit et le nom, je suppose? Semble compliqué. Qu'en pensez-vous?

2) La base de données est un système de comptabilité. Je ne suis pas très familier avec la comptabilité. Au moment sommaire de certaines données sont obtenues et stockées dans la base de données. Par exemple, les ventes totales de l'année. Mon associé senior, a déclaré que les comptables pour vérifier les choses sont correctes en comparant cette valeur avec des données qui est en fait calculée à partir des factures, etc, pour leur donner de la confiance que l'application fonctionne correctement. Il a dit que pour le moment, par exemple, on peut savoir si quelqu'un a supprimé une facture de l'année dernière, à tort, parce que les totaux ne sera pas la même. Il a également souligné qu'il pourrait être assez lent à calculer les totaux à la volée. Bien sûr, j'ai dit que les données ne doivent pas être dupliqués et doit toujours être calculée en cas de besoin. J'ai suggéré que nous pourrions utiliser SQL Reporting Services ou une autre solution qui permettra de générer ces rapports pour la nuit et les mettre en cache. De toute façon, il n'est pas convaincu. Des commentaires sur cette question?

Merci beaucoup :)
Cheers
Marque

MODIFIER

Merci pour les excellentes réponses. C'est dommage, je ne peux drapeau de l'un à la réponse, car il ya beaucoup de bonnes suggestions ici.

51voto

PerformanceDBA Points 9613

Supérieurs de votre collègue est un développeur, pas un modeleur de données. Vous êtes mieux de commencer à partir de zéro, sans eux. La Normalisation est compliqué uniquement à ceux qui ne lisent pas de livres, et de faire passer leur "connaissance" de la les amateurs au wiki. Il est assez juste qu'il vous fait penser, mais certaines questions sont absurdes.

Vos numéros:

  1. Vous avez besoin pour apprécier les différences entre les résultats réels de données en ligne, et les données historiques; ensuite, la différence entre simplement historique et les besoins en matière d'archives. Tous sont en droit spécifique à l'exigence de l'entreprise, et le mal pour tous les autres, il n'y a pas de droit universel et le mal.

    • pourquoi il n'y a pas de papier de la copie de la facture ? Dans la plupart des pays qui serait un cadre juridique et fiscal exigence, quelle est exactement la difficulté de pêche le vieux facture ?
    • où la base de données a l' obligation de stockage de la fermé les factures, c'est sûr que, dès que la facture est fermé, vous avez besoin d'une méthode de capture de l'information.
    • ProductPrice (en fait, je dirais que c' ProductDate) est une bonne idée, mais peut-être pas nécessaire. Mais vous avez raison, vous avez besoin pour évaluer la validité des données, dans le contexte de l'ensemble de la base de données.
    • Je ne vois pas comment copier le produit du prix de la facture de la table de l'aide (ne sont pas là de nombreux éléments de ligne ?)
    • dans des bases de données modernes, où la copie de la facture est nécessaire pour être régurgité, le clos de la Facture est également stockée dans une forme différente, par exemple, XML. Un client enregistre les fichiers Pdf comme des Gouttes. Donc, il n'y a pas de déconner avec ce que le prix du produit était il y a cinq ans. Mais la facture de base de données est en ligne et à jour, même pour les factures; vous ne pouvez pas recalculer l'ancienne facture en utilisant les prix courants.
    • certaines personnes utilisent un archive_invoice table, mais qui a des problèmes parce que maintenant chaque segment de code ou de l'utilisateur de l'outil de rapport de a à regarder à deux endroits (à noter que ces jours, certains utilisateurs à comprendre les bases de données mieux que la plupart des développeurs)
    • De toute façon, c'est-à toutes les discussions, pour votre compréhension. Aucun des bases de données que j'ai écrit dans les 30 dernières années a jamais eu ce genre de problème, et l'ensemble de leur conformité avec les dispositions légales et les obligations en matière fiscale.
      • La base de données sert de courant et à des fins d'archivage à partir d'un ensemble de tables (pas de "archive" tables
      • Une fois qu'une Facture est créée, c'est un document juridique, et ne peut pas être modifié ou supprimé (il peut être inversé ou partiellement attribuée par une nouvelle Facture, avec des valeurs négatives). Ils sont marqués IsIssued/IsPaid/Etc
      • Products ne peuvent pas être supprimés, ils peuvent être marqués IsObsolete
      • Il y a des tables séparées pour les InvoiceHeader et InvoiceItem
      • InvoiceItem a FKs à la fois InvoiceHeader et Product
      • pour de nombreuses raisons (pas seulement ceux que vous mentionnez), le InvoiceItem ligne contient l' NumUnits; ProductPrice; TaxAmount; ExtendedPrice. Bien sûr, cela ressemble à une "dénormalisation" mais il n'est pas, parce que les prix, les taux d'imposition, etc, sont sujettes à changement. Mais le plus important, l'obligation légale est que nous pouvons reproduire le vieux facture sur demande.
      • (où elle peut être reproduite à partir des dossiers sur papier, ce n'est pas nécessaire)
      • l' InvoiceTotalAmount est un dérivé de la colonne, juste SUM() de la InvoiceItems
        .
  2. C'est de la foutaise. Les systèmes comptables et les comptables ne sont pas "travailler" comme ça.

    • Si c'est un véritable système de comptabilité, alors il aura JournalEntries, ou "à double entrée"; c'est ce qui est qualifié de compte est nécessaire pour l'utiliser (par la loi).

      • Double Entrée ne signifie pas entrée en double; il signifie toute transaction financière (une quantité) doit disposer d'un compte source et cible compte qu'il est appliqué; il n'y a pas de "dénormalisation" ou de duplication. Dans une de services bancaires de base de données, parce que les transactions financières sont contre une seule des comptes, qui est généralement traduit comme deux transactions financières (lignes) dans un délai d'un Db Transaction. Ordinaire de la base de données commerciale, les contraintes sont utilisées pour s'assurer qu'il y a deux "côtés" pour chaque transaction financière.
        .
    • Veiller à ce que les Factures ne sont pas deleteable est une question distincte, de la sécurité, etc. si quelqu'un est paranoïaque à propos de choses étant supprimé à partir de leur base de données, et leur base de données n'a pas été garanti par une personne qualifiée, alors qu'ils ont plus de et les différents problèmes qui n'ont rien à voir avec cette question. Obtenir un audit de sécurité, et de faire tout ce qu'ils vous disent.

    • Il y a quelques personnes sur ce site qui pense que le wiki est un endroit que vous pouvez apprendre quelque chose. Il n'est pas. C'est un cloaque de "définitions", écrit par des amateurs, et les "définitions" sont constamment modifiées par d'autres amateurs. Aucune définition précise de ce que vous pouvez compter sur. Alors ne vous inquiétez pas à propos de ce que le wiki dit ou ce que les gens disent wiki dit, du moment qu'ils mentionnent wiki, vous savez leur "connaissance" est venue de la lecture de pas de qualification; et de ce qu'ils lisent est en constante évolution cloaque. Ils prévisible disputent à propos de "définitions" car ils n'ont pas l'expérience réelle; le connu simplement le travail

    • Normalisé de la base de données est toujours beaucoup plus rapide que Unnormalised base de données. Il est donc très important de comprendre ce que la Normalisation et Denormalisaion est, et ce qu'il ne l'est pas. Le processus est grandement entravée lorsque les gens ont des fluides et des amateurs de "définitions", c'est simplement conduit à la confusion et perte de temps "discussions". Lorsque vous aurez résolu les définitions, vous pouvez éviter tout cela, et tout simplement le travail.

    • Les tableaux sont tout à fait normal, pour gagner du temps et de puissance de traitement, de recalculer info qui ne change pas, par exemple: les totaux depuis un an pour chaque année, mais cette année; DMT totaux pour chaque mois de cette année, mais pas ce mois-ci. "Toujours le recalcul des données" est un peu idiot quand (a) l'info est très grand et (b) ne change pas. Calculer pour le mois en cours seulement

      • Dans les systèmes bancaires (en millions de transactions par jour), à EndOfDay, nous calculer et de stocker Quotidienne ainsi. Ces sont remplacés par les cinq derniers jours, parce que Audiitors sont à faire des changements, et JournalEntries contre les transactions financières pour les 5 derniers jours sont autorisés.
      • non-bancaire en général, les systèmes n'ont pas besoin de totaux journaliers
        .
    • Les tableaux de synthèse ne sont pas une "dénormalisation" (sauf dans les yeux de ceux qui ont juste appris à propos de la "normalisation" de leur magie, toujours changeant fluide "source"; ou en tant que non-praticiens, qui s'appliquent simple en noir ou blanc les règles de tout). Là encore, la définition n'est pas soutenu en l'espèce, elle ne s'applique pas à des tableaux récapitulatifs.

    • Les tableaux de synthèse n'affectent pas l'intégrité des données (en supposant bien sûr que les données qu'ils étaient en provenance d'faisait partie intégrante).

    • Les tableaux sont un ajout à la base de données, qui ne sont pas tenus d'avoir les mêmes contraintes que la base de données. Il y a essentiellement des rapports de tableaux ou de tables d'entrepôt de données, plutôt que des tables de base de données.

    • Il n'y a pas de mise à Jour des Anomalies (qui est une définition stricte) liées à des tableaux récapitulatifs. Vous ne pouvez pas modifier ou supprimer une facture de l'année dernière. Mise à jour des Anomalies s'appliquent à vrai Denormalised ou Unnormalised des données actuelles.

13voto

Jeff Ferland Points 9485

1) C'est une archive. Tout ce qui est en elle ne doit jamais être mis à jour. J'irais avec le haut du mec suggestion et ont que la facture de la table autonome. Peut-être utiliser un blob pour la facture elle-même qui contient markup language?

2) Reporting services, un entrepôt, un tableau qui est le point de déclenchement de mise à jour, quelque chose de vous construire par le script à chaque fois que... tous ces bien, je pense. Il est en effet idéal pour être normalisée, mais il n'est pas toujours rapide. J'ai une bonne taille de soins de santé de base de données, je gère qui est entièrement normalisée... et ensuite on a une série de tables normalisées avec roulé équations et souvent tiré des champs. Presque tout fonctionne de que de-normalisée ensemble, c'est juste plus rapide ajouter à ceux-ci avec un déclencheur quand les fichiers sont chargés de garder l'avoir à tirer de diverses tables de chaque fois que je veux regarder une 100 000 rapport.

8voto

Unreason Points 8703

Vous soulevez des points valables, cependant, vous ne sont pas totalement claires sur la normalisation et ce qu'il signifie, par exemple dans

1) La demande de conserver les factures qu'ils ont été denormalizes les données sont complètement et totalement faux. Prenons prix par exemple - si vous avez une exigence de l'entreprise qui indique que vous avez à garder l'historique des prix pour les garder seul prix actuel est mauvais et qu'il brise les exigences. Et il n'a rien à voir avec la normalisation, c'est tout simplement pas conçu ainsi. Dénormalisation de l'est sur l'introduction des possibilités pour de l'ambiguïté dans votre modèle (et autres objets), et dans ce cas vous ne sont tout simplement pas la modélisation de votre espace de problème correctement.
Il n'y a rien de mal dans la modélisation de votre base de données à l'appui des données temporelles (ou le contrôle de version et/ou de séparer les zones de la base de données dans l'archive/temporel et l'ensemble de travail).

En regardant la normalisation sans regarder la sémantique (en termes d'exigences) n'est pas possible.

Aussi, si votre développeur senior ne peut pas voir la différence alors je pense qu'il n'a pas son ancienneté dans le SGBDR de développement ;)

2) la Deuxième partie est en effet la dénormalisation. Toutefois, si vous exécutez à travers les hauts DB analyste qui a gravement prêche la normalisation, vous allez l'entendre lui dire qu'il est parfaitement acceptable de dénormaliser aussi longtemps que vous le faites consciemment et de s'assurer que les avantages de l'embonpoint des lacunes et que les anomalies ne va pas vous mordre. Ils vous diront également de normaliser le modèle logique et que, dans le modèle physique vous êtes autorisé à s'écarter de l'idéal à des fins diverses (rendement, l'entretien, etc...). Dans mon livre, le principal objectif de la normalisation est de sorte que vous n'avez pas les anomalies cachées (voir cet article sur le 5NF par exemple)

La mise en cache des résultats intermédiaires est permis, même sur normalisé bases de données et même par les plus grands évangélistes de normalisation - vous pouvez le faire à la couche application (comme une sorte de cache) ou vous pouvez le faire au niveau base de données ou vous pouvez avoir un entrepôt de données à de telles fins. Ce sont tous des choix valables et n'ont rien à voir avec la normalisation de la logique du modèle.

Aussi, comme votre comptable vous devriez être capable de le convaincre que ce qu'il réclame est pas une bonne façon de tester et de développer un ensemble de tests (peut-être avec lui) qui permettra d'automatiser les tests du système sans que les utilisateurs d'intervention et de vous donner plus de confiance que votre système est exempt de bugs.

D'autre part, je sais de systèmes qui obligent les utilisateurs à entrer des informations en double, comme pour entrer le nombre de lignes sur la facture avant ou après la saisie réelle des lignes, pour s'assurer que l'entrée est terminée. Cette donnée est "dupliqué" et vous n'avez pas à stocker si vous avez une procédure qui permettra de valider l'entrée. Si cette procédure vient plus tard, il est permis de stocker le "anormale" data - encore une fois, la sémantique de la justifier et vous pouvez regarder le modèle normalisé. (il est bénéfique pour envelopper votre tête autour de ce concept)

EDIT: Le terme "anormale" dans (2) n'est pas correct si vous regardez la définition formelle des formes normales, et si vous considérez une conception dénormalisée si il respecte pas l'une des formes normales (pour certaines personnes, c'est évident et il n'y a pas d'autre moyen à ce sujet).

Encore, vous pouvez me faire à l'idée que beaucoup de personnes, et pas nécessaire inutiles des textes à utiliser le terme de normalisation de tout effort qui tente de réduire la redondance dans la base de données (un peu comme un exemple, vous trouverez des articles scientifiques, par qui je ne dis pas qu'ils doivent être à droite, comme un avertissement qu'il est commun, que les appels provenant des attributs d'une forme de dénormalisation, voir ici).

Si vous voulez faire référence à certains plus de cohérence et d'autorités reconnues (encore une fois, n'est pas reconnu par tous), peut-être que les mots de C. J. Date peut faire une distinction claire:

Une grande partie de la théorie de conception de a à faire avec la réduction de la redondance, de la normalisation réduit la redondance dans les relvars, l'orthogonalité de la réduire à travers relvars.

qouted à partir de la Base de données en profondeur: la théorie relationnelle pour les praticiens

et sur la page suivante

tout comme un échec à normaliser tous les implique la redondance et peut conduire à certaines anomalies, ce qui peut avoir un le non respect de l'orthogonalité.

Donc, le terme approprié pour une redondance à travers relvars est d'orthogonalité (en gros toutes les formes normales parler seul relvar donc, si vous regardez strictement à la normalisation qu'il ne serait jamais suggérer d'éventuelles améliorations à cause des dépendances entre les différents relvars).

De toute façon, l'un des autres concepts importants lorsque vous envisagez de conception de base de données est également une différence entre logique et physique de la base de données des modèles. Beaucoup de choses qui sont utiles sur le plan physique, tels que des tables avec des sous-totaux ou les index n'ont pas de place dans le modèle logique - où vous essayez d'établir et étudier les relations entre les concepts que vous essayez d'modèle. Et c'est pourquoi on peut dire qu'ils sont acceptables et qu'ils ne ruine pas le design.

Les lignes peuvent être parfois un peu floue sur ce qui est logique du modèle et ce qui est du modèle physique. En particulier, par exemple un tableau avec des sous-totaux. Pour les considèrent comme faisant partie de la mise en œuvre physique et l'ignorer sur le niveau logique, vous devez:

  • s'assurer que les utilisateurs (et la demande) ne peut pas mettre à jour la sous-total tableau directement dans une manière qui n'est pas compatible avec leur prédicat (dans un autre mots ont un bug dans le subtotalling procédure)
  • s'assurer que les utilisateurs (et la demande) ne peut pas mettre à jour la table sur laquelle elles sont dépendantes sans mise à jour de la sous-total (en d'autres termes que certaines applications ne seront pas supprimer une ligne de la table de détail sans mettre à jour le total)

Si vous violez l'une des règles ci-dessus, vous vous retrouverez avec base de données incohérente qui fournira incompatible faits. (Dans ce cas, si vous voulez officiellement la conception d'une procédure de résolution ou d'examiner les problèmes causés, vous ne voudrais pas le considérer simplement une table supplémentaire, il existerait au niveau logique; là où il ne devrait pas être).

Aussi, la normalisation dépend toujours de la sémantique et les règles de gestion que vous essayez d'modèle. Par exemple DBAPerformance donne un exemple dans lequel le stockage de l' TaxAmount dans la table des transactions n'est pas anormale de la conception, mais il omet de mentionner que cela dépend de ce genre de système que vous essayez d'modèle (est-ce évident?); par exemple, si la transaction a un autre attribut qui s'appelle TaxRate il sera généralement dénormalisée, car il y a de la dépendance fonctionnelle sur un ensemble d'attributs non-clé (TaxAmount = Quantité * TaxRate => FD: Montant,TaxRate -> TaxAmount), et l'une d'elles doit être supprimé ou être cohérentes.

Évidemment, direz-vous, mais, si le système de construction est une société d'audit, alors vous pourriez ne pas avoir de dépendance fonctionnelle - ils peut-être l'audit de quelqu'un qui est à l'aide de calculs manuels ou a logiciel défectueux ou doit avoir la capacité d'enregistrer des données incomplètes et le calcul pourrait être mal à l'origine, et en tant que société d'audit, vous devez enregistrer le fait qu'il s'est passé.

Ainsi, la sémantique (prédicats) qui sont déterminés par les exigences de l'influence si l'une des formes normales sont brisés en influençant les dépendances fonctionnelles (en d'autres termes correctement établir des dépendances fonctionnelles est assez importante partie de la modélisation lorsque vous vous efforcez de base de données normalisée).

5voto

sqlvogel Points 12567

1) Ne nécessite pas de dénormalisation. Vous avez juste besoin de déterminer le niveau de détail de chaque changement dont vous avez besoin et de le conserver avec une clé appropriée.

2) N'a rien à voir avec la dénormalisation. Le stockage de données récapitulatives ne rend pas la base de données dénormalisée. Stocker des résultats dérivés d'attributs non-clés dans la même table serait un exemple de dénormalisation, mais cela ne semble pas être ce dont vous parlez ici.

5voto

Jonathan Rand Points 21

Votre développeur senior rend extrêmement valable points. J'ai appris que ces à la dure par moi-même l'entretien de systèmes qui ne sont pas de normaliser les données historiques.

Dans un sens, c'est pas vraiment l'ajout de frais généraux à la base de données. Vous êtes à la création de la facture des tables à partir des données existantes dans la base de données. Une facture est un instantané dans le temps. De normaliser l'information dont vous avez besoin pour produire cette facture peut rendre votre établissement de rapports de manière beaucoup plus facile. Lorsque vous sont nécessaires pour produire un nouveau rapport et devrait le faire rapidement, vous apprécierez la dénormalisation.

En termes de total dans la base de données. Ce qui a sauvé mon cul avant quand j'ai apporté une modification à une demande qui a provoqué les numéros de ne pas ajouter de la même façon (pas aussi difficile que vous pouvez penser). Sur une application en direct les totaux m'a donné une certaine place dans le but de corriger les écarts. J'ai écrit à ce sujet avant, vous pouvez le lire ici: http://jlrand.com/?p=95

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X