Das Interessante an diesem Q & A-Thread ist, dass es tatsächlich 3 Fragen gibt. Jeder hat einen anderen beantwortet, und fast niemand hat den ersten beantwortet:
- Warum werden einige Datenbanken nicht normalisiert?
- Warum / wann sollte eine normalisierte Datenbank denormalisiert werden ?
- In welchen Situationen ist es schädlich oder unnötig, sich überhaupt zu normalisieren?
Hinweisleser werden bemerken, dass dies sehr unterschiedliche Fragen sind, und ich werde versuchen, jede für sich zu beantworten, wobei zu viele Details vermieden werden. Mit "zu viel" meine ich, dass dies nicht der geeignete Kontext ist, um eine ausführliche Debatte über die Begründetheit verschiedener Argumente für oder gegen die Normalisierung zu führen. Ich werde einfach erklären, was diese Argumente sind, vielleicht ein paar Einschränkungen auflisten und die Philosophie für spezifischere Fragen speichern, falls sie jemals auftauchen.
Außerdem gehe ich in dieser Antwort davon aus, dass "Normalisierung" "BCNF, 3NF oder mindestens 2NF " impliziert , da dies der Grad der Normalisierung ist, den Designer im Allgemeinen anstreben. Es ist seltener, 4NF- oder 5NF-Designs zu sehen. Obwohl es sich sicherlich nicht um unmögliche Ziele handelt, befassen sie sich mit der Semantik von Beziehungen und nicht nur mit deren Repräsentation , was wesentlich mehr Wissen über den Bereich erfordert.
Also vorwärts und aufwärts:
1. Warum werden einige Datenbanken nicht normalisiert?
Die Antwort auf diese Frage könnte lauten "weil sie es nicht sein sollten", aber diese Vermutung auf Anhieb zu machen, ist eine ziemlich pissarme Detektivarbeit. Wir würden als Gesellschaft nicht sehr weiterkommen, wenn wir immer davon ausgehen würden, dass das, was auch immer ist, es sein sollte.
Die wahren Gründe, warum Datenbanken überhaupt nicht normalisiert werden, sind komplizierter. Hier sind die Top 5, auf die ich gestoßen bin:
Die Entwickler, die es entworfen haben, wussten oder verstanden nicht, wie man es normalisiert. Ein starker Beweis dafür sind viele andere schlechte Designentscheidungen, wie die Verwendung von varchar-Spalten für alles oder das Durcheinander bedeutungsloser Tabellen- und Spaltennamen . Und ich versichere Ihnen, ich habe "echte" Datenbanken gesehen, die genauso schlecht sind wie die in den TDWTF-Artikeln.
Die Entwickler, die es entworfen haben, haben sich aus Prinzip nicht darum gekümmert oder waren aktiv gegen Normalisierung . Ich spreche hier nicht von Fällen, in denen absichtlich entschieden wurde, nicht auf der Grundlage von Kontextanalysen zu normalisieren, sondern von Teams oder Unternehmen, in denen Normalisierung mehr oder weniger verstanden, aber einfach ignoriert oder aus Gewohnheit gemieden wird. Wieder überraschend häufig.
Die Software wird / wurde als Brownfield-Projekt erstellt . Viele Puristen ignorieren dieses absolut legitime Geschäft und nicht den technischen Grund, sich nicht zu normalisieren. Manchmal ist es nicht möglich, eine neue Datenbank von Grund auf neu zu entwerfen, sondern Sie müssen sich auf ein vorhandenes Legacy-Schema beschränken, und der Versuch, an diesem Punkt zu normalisieren, würde viel zu viel Aufwand bedeuten. 3NF wurde erst 1971 erfunden und einige Systeme - insbesondere Finanz- / Buchhaltungssysteme - haben ihre Wurzeln noch weiter zurück!
Die Datenbank wurde ursprünglich normalisiert , aber eine Ansammlung kleiner Änderungen über einen langen Zeitraum und / oder ein weit verbreitetes Team führten subtile Formen der Vervielfältigung und andere Verstöße gegen die ursprüngliche Normalform ein. Mit anderen Worten, der Normalisierungsverlust war zufällig und es wurde zu wenig Zeit für die Umgestaltung aufgewendet.
Es wurde absichtlich die Entscheidung getroffen, keine Zeit für Geschäftsanalysen oder Datenbankentwürfe aufzuwenden und einfach "fertig" zu werden. Dies ist oft eine falsche Ökonomie und wird letztendlich zu einer Form der technischen Verschuldung , ist aber manchmal eine rationale Entscheidung, zumindest basierend auf Informationen, die zu der Zeit bekannt waren - zum Beispiel könnte die Datenbank als Prototyp gedacht gewesen sein, aber am Ende stehen aufgrund von Zeitbeschränkungen oder Änderungen im Geschäftsumfeld in den Produktionsbetrieb befördert werden.
2. Warum / wann sollte eine normalisierte Datenbank denormalisiert werden?
Diese Diskussion kommt oft auf , wenn eine Datenbank wird normalisiert zu beginnen. Entweder ist die Leistung schlecht oder die Abfragen (Joins) sind doppelt vorhanden, und das Team ist zu Recht oder zu Unrecht der Meinung, dass es mit dem aktuellen Design so weit wie möglich gekommen ist. Es ist wichtig zu beachten, dass die Normalisierung die meiste Zeit die Leistung verbessert. Es gibt verschiedene Möglichkeiten, um übermäßige Verknüpfungen zu beseitigen, wenn die Normalisierung gegen Sie zu wirken scheint. Viele davon sind weniger invasiv und riskant als der einfache Wechsel zu einem denormalisierten Modell:
Erstellen Sie indizierte Ansichten, in denen die häufigsten Problembereiche zusammengefasst sind. Moderne DBMS können sie einfügbar oder aktualisierbar machen (z. B. SQL Server- INSTEAD OF
Trigger). Dies ist für DML-Anweisungen in den zugrunde liegenden Tabellen / Indizes mit geringen Kosten verbunden, aber im Allgemeinen die erste Option, die Sie ausprobieren sollten, da es nahezu unmöglich ist, Fehler zu machen, und fast nichts kostet, diese zu warten. Natürlich kann nicht jede Abfrage in eine indizierte Ansicht umgewandelt werden - aggregierte Abfragen sind am schwierigsten. Was uns zum nächsten Punkt führt ...
Erstellen Sie denormalisierte Aggregattabellen, die von Triggern automatisch aktualisiert werden. Diese Tabellen existieren zusätzlich zu den normalisierten Tabellen und bilden eine Art CQRS- Modell. Ein anderes CQRS-Modell, das heutzutage immer beliebter wird, ist die Aktualisierung der Abfragemodelle mithilfe von Pub / Sub, was den Vorteil der Asynchronität bietet. Dies ist jedoch möglicherweise in sehr seltenen Fällen ungeeignet, in denen die Daten nicht veraltet sind.
Manchmal sind indizierte Ansichten nicht möglich, die Transaktionsraten und das Datenvolumen sind zu hoch, um Trigger mit akzeptabler Leistung zuzulassen, und die Abfragen müssen immer Echtzeitdaten zurückgeben. Diese Situationen sind selten - ich würde vermuten, dass sie auf Dinge wie Hochfrequenzhandel oder Strafverfolgungs- / Nachrichtendatenbanken zutreffen - aber sie können existieren. In diesen Fällen haben Sie wirklich keine andere Wahl, als die Originaltabellen zu denormalisieren.
3. In welchen Situationen ist es schädlich oder unnötig, sich überhaupt zu normalisieren?
Tatsächlich gibt es hier einige gute Beispiele:
Wenn die Datenbank nur für die Berichterstellung / Analyse verwendet wird. In der Regel bedeutet dies, dass für OLTP eine zusätzliche , normalisierte Datenbank verwendet wird, die regelmäßig über ETL oder Messaging mit der Analysedatenbank synchronisiert wird.
Bei der Durchsetzung eines normalisierten Modells wäre eine unnötig komplexe Analyse der eingehenden Daten erforderlich. Ein Beispiel hierfür ist möglicherweise ein System, das Telefonnummern speichern muss, die von mehreren externen Systemen oder Datenbanken gesammelt wurden. Sie könnten die Rufnummer und die Ortsvorwahl denormalisieren, müssten jedoch alle möglichen Formate, ungültigen Telefonnummern und Vanity-Nummern (1-800-GET-STUFF) berücksichtigen, ganz zu schweigen von den verschiedenen Ländereinstellungen. Es ist normalerweise mehr Mühe als es wert ist, und Telefonnummern werden normalerweise nur in ein einzelnes Feld eingegeben, es sei denn, Sie haben einen bestimmten Geschäftsbedarf für die Vorwahl alleine.
Wenn die relationale Datenbank in erster Linie dazu dient, Transaktionsunterstützung für eine zusätzliche, nicht relationale Datenbank bereitzustellen. Beispielsweise können Sie die relationale Datenbank als Nachrichtenwarteschlange verwenden oder den Status einer Transaktion oder Saga verfolgen, wenn die primären Daten in Redis oder MongoDB oder in einem anderen Verzeichnis gespeichert sind. Mit anderen Worten sind die Daten "Steuerdaten". Normalerweise macht es keinen Sinn, Daten zu normalisieren, die eigentlich keine Geschäftsdaten sind .
Serviceorientierte Architekturen, die eine physische Datenbank gemeinsam nutzen. Dies ist ein bisschen seltsam, aber in einer echten SOA müssen gelegentlich Daten physisch dupliziert werden, da die Dienste nicht direkt die Daten der anderen abfragen dürfen. Wenn sie passieren die gleiche physische Datenbank zu teilen, werden die Daten erscheinen nicht normalisiert werden - aber in der Regel, die von jedem einzelnen Dienst eigenen Daten sind immer noch normalisieren es sei denn , eine der anderen schadensbegrenzenden Faktoren an seinem Platz ist. Ein Abrechnungsdienst besitzt möglicherweise die Entität "Rechnung", der Abrechnungsdienst muss jedoch das Rechnungsdatum und den Rechnungsbetrag empfangen und speichern, damit er in den Umsatz für dieses Jahr einbezogen werden kann.
Ich bin sicher, dass es weitere Gründe gibt, die ich nicht aufgelistet habe. Was ich im Wesentlichen verstehe, ist, dass sie ziemlich spezifisch sind und ziemlich offensichtlich sein werden, wenn sie in der Praxis auftauchen. OLAP-Datenbanken sollten Sternschemata verwenden, SOAs sollten einige Duplikate aufweisen usw. Wenn Sie mit einem bekannten Architekturmodell arbeiten, das mit Normalisierung einfach nicht funktioniert, werden Sie nicht normalisiert. Im Allgemeinen hat das Architekturmodell Vorrang vor dem Datenmodell.
Und um die allerletzte Frage zu beantworten:
Stimmt es, dass gute Architekten und Experten ein denormalisiertes Design wählen, während nicht erfahrene Entwickler das Gegenteil wählen? Was sind die Argumente gegen den Beginn Ihres Entwurfs im Hinblick auf Normalisierung?
Nein, das ist ein vollständiges und vollständiges BS. Es ist auch BS, dass Experten immer ein normalisiertes Design wählen . Experten folgen nicht nur einem Mantra. Sie recherchieren, analysieren, diskutieren, klären und iterieren und wählen dann den Ansatz, der für ihre jeweilige Situation am sinnvollsten ist.
Die 3NF- oder BCNF-Datenbank ist in der Regel ein guter Ausgangspunkt für die Analyse, da sie sich in Zehntausenden von Projekten auf der ganzen Welt bewährt hat, aber auch in C. Das bedeutet nicht, dass wir C automatisch in allen Projekten verwenden neues Projekt. In realen Situationen können einige Änderungen am Modell oder die Verwendung eines anderen Modells erforderlich sein. Sie wissen es nicht, bis Sie in dieser Situation sind.