|
PHP Wiki Dieses Wiki sammelt Lösungen, zu Problemen, welche immer wieder im Forum auftauchen. |
|
Artikel-Optionen | Ansicht |
#1
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
DatenbanknormalisierungVorwortDatenbanknormalisierung ist eigentlich ein schreckliches Wort. Normalisierung, das heißt Angleichung an die Masse und das ist wahrscheinlich die schlimmste Form der Gleichmacherei. Warum also diese Gleichmacherei? Meine Anwendung ist schließlich ein Kunstwerk für sich. ![]() Nun, es haben sich ja schon recht viele Leute mit dem Thema Erstellung relationaler Datenbanken beschäftigt. Viele sind auf Probleme und Lösungen gestoßen, und natürlich wurde vieles davon auch publiziert. Heraus gekommen ist ein Satz von Regeln, "Best Practices", wenn Ihr so wollt, für die Erstellung von Datenlayouts in relationalen Datenbanken. Ziel dieser Regeln ist es, Redundanzen zu vermeiden und einen effizienten Zugriff auf die Daten zu ermöglichen. Warum Redundanzen vermeiden, werdet Ihr vielleicht fragen. Gut - die Frage ist berechtigt, schließlich ist fast nichts heutzutage so preiswert zu haben, wie Speicherplatz. Trotzdem darf hier nicht nur die Kostenfrage betrachtet werden, sondern es muss auch die Frage des schnellen Zugriffs gestellt werden. Wenn sich Eure Daten in tausendfacher Form an den unterschiedlichsten Stellen befinden, dann muss für jede Suche, für jede Veränderung und für das Hinzufügen jedes neuen Datenwertes ein überdimensionaler Aufwand getrieben werden. Auch eine anderer Aspekt darf natürlich nicht vergessen werden, und das ist die Frage nach der referentiellen Integrität. Wenn eine Information an fünf Orten steht, dann wird bei einer Änderung schnell auch nur mal einer dieser Orte verändert. Folge sind Strukturprobleme innerhalb der Vernetzung der Daten. All das - und natürlich die Spezialisierung, die sich mittlerweile in die technische Umsetzung relationaler Datenbankmanagementsysteme eingeschlichen hat - nimmt zwar auf den ersten Blick Freiheiten, auf lange Sicht hat sich die Einhaltung diverser Best Practices aber noch immer für jedes Projekt gelohnt und der Mehraufwand hat sich bisher noch immer rentiert. Die fünf Normalformen. Oder waren es doch sieben?Um mit den Inhalten einer Datenbank effizient umgehen zu können, haben sich - wie schon erwähnt - einige Best Practices, namens "Normalformen" etabliert. Diese Normalformen sind allerdings keine Regeln, die alle für sich alleine stehen, sondern die einzelnen Normalformen bauen aufeinander auf. Erfüllt eine Datenstruktur/ein Datenlayout die Normalform 2, so muss sie per Definition auch die Normalform 1 erfüllen, damit alle Kriterien für NF 2 gewahrt sind. Essentiell für das Verständnis vieler der folgenden Definitionen ist das Verständnis der Begrifflichkeiten Key oder Schlüssel und funktionale Abhängigkeit. Erstere Begriffe werden Synonym verwendet und bezeichnen eine Möglichkeit, bestimmte Datensätze eindeutig zu identifizieren, der zweite wird zur Beschreibung von Logikzusammenhängen zwischen Datenworten innerhalb eines Datensatzes genutzt.
Tipp: Eine gute technische Erklärung zur Nutzung von Schlüsseln in relationalen Datenbankmanagementsystemen bietet dieses Online-Buch. Historisch gehen zumindest die ersten 3.5 der im folgenden näher beschriebenen Normalformen auf den Englischen Computerwissenschaftler Edgar F. Codd zurück, die höheren auf die Arbeiten und Publikationen anderer Fachleute, die sich aber zumindest an der Arbeit von Codd orientieren. In der Praxis relevant sind hauptsächlich die Normalformen eins bis drei, sowie die Boyce-Codd-Normalform. Ein beharren auf die letzten drei Normalformen (4, 5 und 6) ist in der Fachwelt teilweise umstritten, da ihre Anwendung teilweise zu Performance-Problemen im praktischen Einsatz führt. Das macht die letzten Normalformen allerdings um nichts weniger wichtig. Der generelle Konsens ist wohl, dass auch diese berücksichtigt werden sollten, sofern keine explizite technische Anforderung das aktuellen Anwendungsfalles sie verhindert. Alle anderen sprechen immer von fünf Normalformen. Warum spricht dieser Artikel von sieben? Die Begründungen dafür sind denkbar einfach: Eine der Normalformen - die Boyce-Codd-Normalform - liegt im Sprachgebrauch völlig außerhalb des gewöhnlichen Zählschemas, da viele in ihr einfach nur eine Erweiterung einer bestehenden Normalform sehen. Das lässt Normalform 6 - diese gewinnt erst seit 2002 Bekanntheitsgrad. Sie kommt allerdings aus einigermaßen berufenem Munde, deshalb wird sie hier der Vollständigkeit halber mit aufgeführt. Ob sie sich in der Praxis durchsetzt? Wir werden sehen. Nun wollen wir uns die unterschiedlichen Normalformen und Regeln mal im Detail anschauen und mit kleinen Beispielen versehen: 1. NormalformDefinitionIn jede Spalte einer Tabelle kommt exakt eine Information, also etwas, das nicht sinnvoll in kleinere Teile zerlegt werden kann. Beispiel IDie Adresse "12345 Kleindödelhausen, Hauptstraße 123" steht in einem Textfeld "adresse" innerhalb einer Tabelle. Zweck/GrundSelektionen auf Teilinformationen - z.B. "alle Kunden aus Kleindödelhausen" - sind nicht mehr effizient/einfach durchführbar, wenn alle diese Informationen in einer Spalte stehen. Lösung:Die Adresse sollte in vier bis fünf Spalten abgelegt werden: Beispiel II:Ein gern gemachter Anfängerfehler ist es, Kommaseparierte Werte in einer einzelnen Spalte der Tabelle zu platzieren. Nehmen wir an, wir wollen eine Liste von Fußballspielern, inklusive Ihrer Positionen erstellen. Häufig entsteht dabei dann so etwas hier: Lösungsansatz I zu Beispiel II
Lösungsansatz II zu Beispiel IIZwei Tabellen, eine für die Positionen und eine für die Spieler sind hier der Weg, der keiner bekannten Definition der ersten Normalform wiederspricht: 2. NormalformDefinitionAlle Daten, die nicht Teil des Keys sind, hängen von allen Key-Attributen ab. BeispielIn einer Tabelle mit den Spalten "KundenNr", "BestellNr", "KundenName", "KundenAlter" und "Artikel" liegt ein Key auf KundenNr und BestellNr. (Im Beispiel kursiv gekennzeichnet) Zweck/GrundEs werden Datenintegritätsverletzungen durch Redundanz möglich, wie z.B. zwei Einträge mit gleicher KundenNr, aber unterschiedlichem KundenNamen oder zwei identische Kunden mit unterschiedlichem Alter. Lösung:Alle Spalten entfernen, die nur von einem Teil des Keys abhängen und in eine eigene Tabelle auslagern. Für das Beispiel oben ergibt sich damit dieses Bild: 3. NormalformDefinitionEs gibt keine transitiven ("mehrstufigen") Abhängigkeiten zwischen den Nicht-Schlüssel-Spalten einer Tabelle. BeispielIn einer Datenbank sollen die Gewinner des jährlich stattfindenden Sportturniere des alt-erwürdigen Klein Kleckersdorfer Hampel-, Hüpf und Springvereins verwaltet werden. LösungZerlegung der o.g. Tabelle in zwei - einmal die Personen, samt ihrer Attribute, und auf der anderen Seite das Turnier, das Jahr und eine Verknüpfung zur Person:
Tipp: Ob Ihr das soweit verstanden habt, könnt Ihr z.B. anhand von diesem kleinen Online-Quiz ja mal testen. Boyce-Codd-Normalform (BCNF)DefinitionDie Boyce-Codd-Normalform ist eine strengere Variante der 3.Normalform: jede Spalte, von der eine andere (funktional) abhängig ist, ist Teil des Keys. Zweck/GrundBeseitigung aller restlichen, redundanten Informationen und Ersatz durch geeignete Relationen. BeispielIn der Lösung zur 2. Normalform haben wir einen solchen Fall: LösungAbhängigkeiten, die nicht in der Form "Attribut hängt ab von Key" sind, in eine separate Tabelle (inkl. der abhängigen Attribute) auslagern. Also: 4. NormalformDefinitionAlle voneinander vollständig unabhängigen Attribute werden in getrennten Tabellen gehalten. Beispiel:
Lösung:Aufteilung in 5. NormalformDefinitionKeine Relation läßt sich in (noch) einfachere Relationen zerteilen, ohne Informationen zu verlieren. Und jetzt? Muss das wirklich alles sein?Das war evtl. etwas schwer verständlich, hier ist eine ausführlichere Variante, die aber auch noch ziemlich akademisch ist. Und Nein, natürlich muss das nicht alles sein. Das geschriebene sind "Best Practices", von denen man in konkreten Fällen manchmal durchaus auch abweichen kann und muss. Trotzdem hat sich etabliert, zumindest die ersten drei der o.g. Normalformen als Qualitätsmaßstab für ein Datenlayout zu interpretieren. Sollte Deine eigene Datenstruktur also eine dieser Regeln verletzen, dann ist es spätestens jetzt an der Zeit, etwas dagegen zu tun. Zum besseren Verständnis der Materie sei Euch insbesondere das Anfänger freundliche Kapitel Datenbanken entwickeln aus DSP: Datenbank, MySQL und PHP von Christoph Reeg und Jens Hatlak, sowie der oben schon einmal angesprochene Wikipedia-Artikel zum Thema Normalisierung von Datenbanken ans Herz gelegt. Ebenfalls gut zu lesen sind die Ausführungen von Prof. Dr. Staud von der HS Weingarten zum Thema Relationale Datenmodellierung. Auch ganz unterhaltsamer Lesestoff - wenn auch teilweise nicht grade für Laien geschrieben - ist Codd's Buch The Relational Model for Database Management (ISBN 0-201-14192-2). Immer wieder stolpert man auch über Temporal Data & the Relational Model von C.J. Date, Hugh Darwen und Nikos Lorentzos (ISBN 1-55860-855-9), zu dessen Qualität der Autor dieses Tutorials allerdings nicht viel erhellendes von sich geben kann. Jetzt komm ich aber viel schwerer an meine Daten wieder ran!Tja, der liebe Zugriff... Natürlich ist es auf den ersten Blick einfacher, wenn alle Daten in einer Tabelle stehen und man mit einem einfachen SELECT ohne viel Fachkenntnisse auf diese Zugreifen kann. Andererseits sind die heutigen relationalen Datenbankmanagementsysteme aber auf genau die in den Normalformen beschriebenen strukturiert verteilten Informationen ausgelegt und können damit für gewöhnlich sehr gut um. Um dem DBMS jetzt allerdings begreiflich machen zu können, welche Daten in welcher Form abgefragt oder verändert werden sollen, bedarf es ein bisschen Kenntnissen in SQL. Zumindest mit ein bisschen relationaler Algebra und mit der Theorie von SQL Joins werdet Ihr Euch auseinander setzen müssen, wenn das ganze funktionieren soll. Wenn Ihr das allerdings hinter Euch habt, dann werdet Ihr schnell merken, dass viele Dinge unter Berücksichtigung der oben beschriebenen Prinzipien nicht nur einfacher, sondern auch bei weitem weniger Fehleranfällig umsetzbar sind. Ganz abgesehen davon, seid Ihr hier ja aber auch in einem Forum. Wenn Ihr also Probleme bei der Umsetzung Eurer Abfragen auf eine normalisierte Datenstruktur habt, dann findet sich sicherlich hier auch schnell jemand, der Euch bei der Lösung hilft. ![]()
Tipp: Weitere Informationen findet Ihr außerdem in den Tutorials A Visual Explanation of SQL Joins und SQL und relationale Algebra.
|
Lesezeichen |
Artikel-Optionen | |
Ansicht | |
|
|