DBnormalizer Das Tutorial


Tutorial

Gegeben ist immer ein Schema bestehend aus den Attributen der Relation und den Funktionalen Abhängigkeiten (FDs) bzw. Mehrwertigen Abhängigkeiten (MVDs).

Beispiel:

R:={ABCDE}
AB->C
B->DA
D->AC
B->C
C->>A

Schlüsselbestimmung

Zunächst müssen wir alle Kandidatenschlüssel bestimmen, das sind alle Mengen von Attributen, die minimal sind und mithilfe denen sich alle anderen Attribute über die FDs erreichen lassen. Am einfachsten ist es, erstmal alle Attribute zu finden, die nirgendwo rechts stehen. Alle diese Attribute müssen auf jeden Fall in jeden Schlüssel. Wir betrachten das Schema von oben: hier tauchen die Attribute B und E nirgendwo rechts auf. Achtung, vergiss hier nicht das Attribut E! Das Attribut E kommt nämlich in keiner FD irgendwo vor und wird somit oft fälschlicherweise übersehen.

Jetzt schauen wir, ob BE tatsächlich ein Schlüssel ist. Durch die zweite FD erreichen wir DA von B aus, über alle anderen FDs danach auch noch das C, womit wir alle Attribute entweder vorher schon hatten oder über die FDs erreichen konnten. Aber pass auf, es muss nicht unbedingt so sein, dass alles, was rechts nirgendwo steht, auch der Schlüssel ist; möglicherweise reicht das nicht aus, um alles andere zu erreichen. In diesem Fall muss man dann schauen, welche Attribute noch hinzugefügt werden müssen, damit man alles erreichen kann. Auch mehrere Kandidatenschlüssel sind möglich. Außerdem wichtig: MVDs werden bei der Schlüsselbestimmung komplett ignoriert; nur die FDs müssen hier betrachtet werden.

Wir wissen jetzt also, dass wir genau einen Kandidatenschlüssel haben, nämlich

{BE}


Normalform bestimmen

Als nächstes bestimmen wir die höchste Normalform, in der sich die Relation befindet. Ein Schema ist in einer bestimmten Normalform, wenn entsprechende Bedingungen vom Schema erfüllt werden.

1NF

Wir fangen bei der ersten Normalform (1NF) an:

Das Schema ist in 1NF, wenn...
...alle Attribute atomar sind.

Das heißt, dass jedes Attribut einen Wert (und keine Liste/Menge von Werten) enthalten muss. Das ist bei uns (wenn nicht explizit anders angegeben) immer erfüllt. Die erste Normalform ist also auch für das obige Schema erfüllt:

1NF

2NF

Die 1NF ist erfüllt, also überprüfen wir als nächstes die 2NF. Die ist nicht ganz so trivial:

Das Schema ist in 2NF, wenn...
...es in 1NF ist und für jedes Attribut b auf der rechten Seite gilt:
  1. b ist Teil eines Kandidatenschlüssels oder
  2. b ist nicht von einer echten Teilmenge eines Kandidatenschlüssels abhängig

Wir müssen jetzt also jede rechte Seite von jeder FD anschauen. Wenn wir ein Attribut rechts finden, das keine der beiden Bedingungen erfüllt, ist das Schema nicht in 2NF.

Also schauen wir uns mal die erste FD

AB->C

an. C (das einzige Attribut rechts) ist nicht Teil eines Kandidatenschlüssels (Bedingung 1), es ist aber auch nicht von einer echten Teilmenge eines Kandidatenschlüssels abhängig. AB ist nämlich keine echte Teilmenge unseres einzigen Kandidatenschlüssels BE, somit ist die zweite Bedingung erfüllt und die erste FD verletzt somit nicht die 2NF. Also machen wir weiter und betrachten die zweite FD

B->DA

Schauen wir uns das erste Attribut rechts (D) an. D ist auch kein Teil eines Kandidatenschlüssels, ist aber abhängig von einer echten Teilmenge unseres Kandidatenschlüssels (B ist echte Teilmenge von BE). Hier ist also auch die zweite Bedingung verletzt, somit haben wir schon eine "böse" FD gefunden; wir können also direkt aufhören und sagen: die 2NF ist nicht erfüllt:

2NF

Da eine höhere Normalform alle niedrigeren Normalformen mit einschließt, können wir jetzt komplett aufhören und müssen gar nicht mehr die 3NF, BCNF und 4NF überprüfen. Heißt: wenn ein Schema nicht in 2NF ist, dann kann es auch nicht in 3NF usw. sein. Die höchste Normalform ist also für unser Beispiel die erste Normalform:

1NF

Wir schauen uns aber trotzdem noch die anderen Normalformen an. Hier wäre das wie beschrieben nicht nötig, weil wir schon wissen, dass die nicht erfüllt sind, aber sonst käm das ja gar nicht im Tutorial vor ;)

3NF

Hier also die Bedingungen für die 3NF:

Das Schema ist in 3NF, wenn...
...jede FD α->β mindestens eine der folgenden Bedingungen erfüllt:
  1. α->β ist trivial (β⊆α)
  2. α ist Superschlüssel
  3. Jedes Attribut in β ist in einem Kandidatenschlüssel enthalten

Offensichtlich ist z.B. die erste FD nicht in 3NF: AB->C ist weder trivial, noch steht links ein Superschlüssel, noch ist das C auf der rechten Seite in einem Kandidatenschlüssel enthalten. Wir können hier also schon aufhören und sagen: 3NF ist nicht erfüllt. In diesem Beispiel ist es sogar so, dass keine der FDs die 3NF erfüllen würde. Also ganz klar (was wir auch schon vorher wussten):

3NF

BCNF

Wenn wir die BCNF überprüfen wollen würden, dann würden wir folgendes checken:

Das Schema ist in BCNF, wenn...
...jede FD α->β mindestens eine der folgenden Bedingungen erfüllt:
  1. α->β ist trivial (β⊆α)
  2. α ist Superschlüssel

Man sieht sofort, dass im Vergleich zur 3NF nur die letzte Bedingung verschwunden ist. Man kann also 3NF und BCNF gleichzeitig prüfen: Wenn ein Schema in 3NF ist, aber man mal die dritte Bedingung "nutzen" muss, weiß man direkt, dass es zwar in 3NF ist, aber nicht in BCNF. Unser Beispiel war ja schon eh nicht in 3NF und deshalb schon lange nicht in BCNF. Sieht man natürlich auch an den Bedingungen der BCNF; keine der FDs erfüllt irgendeine davon.

BCNF

4NF

Für die 4NF betrachten wir erstmals auch zusätzlich die MVDs. Ansonsten sind die Bedingungen quasi die selben wie bei der BCNF:

Das Schema ist in 4NF, wenn...
...jede MVD α->>β mindestens eine der folgenden Bedingungen erfüllt:
  1. α->>β ist trivial (β⊆α oder α∪β = R)
  2. α ist Superschlüssel

Da jede FD auch eine MVD ist, kann ein Schema, das nicht in BCNF ist, auch nicht in 4NF sein. In unserem Beispiel stellen wir uns jetzt alle FDs als MVDs vor und sehen schon (wie vorher), dass z.B. die erste MVD AB->>C keine der Bedingungen erfüllt. Es ist sogar so, dass nichtmal eine MVD (also wie vorher keine der FDs und auch nicht die "reine" MVD C->>A) eine der Bedingungen erfüllt. Zu beachten ist, dass für MVDs eine leicht andere Definition von trivial gilt. Wir wussten es zwar schon vorher, aber haben jetzt nochmal gesehen:

4NF


Kanonische Überdeckung

Wir wollen nun die Kanonische Überdeckung der gegebenen FDs ermitteln. Die Kanonische Überdeckung ist äquivalent zu den ursprünglichen FDs, ist aber im Gegensatz zu den ursprünglichen FDs in jedem Fall minimal (d.h. es gibt keine "Redundanzen" mehr). Zur Bestimmung der Kanonischen Überdeckung müssen vier Schritte nacheinander durchgeführt werden:

Linksreduktion

Als erstes schauen wir, welche Attribute wir auf den linken Seiten weglassen können, ohne die Aussage der FDs zu verändern. In unserem Beispiel können wir - wenn überhaupt - nur die erste FD linksreduzieren; bei allen anderen FDs steht links nur ein Attribut. Würden wir da was weglassen stünde links die leere Menge und die Aussage der FD wäre komplett anders als vorher. Und das wollen wir nicht.

Wir betrachten also die erste FD

AB->C

Erste Frage lautet jetzt also: "Kann ich A weglassen?". Anders formuliert: "Komme ich mit dem Rest trotzdem zur kompletten rechten Seite?". Die Antwort: Ja, weil man kommt auch nur mit dem B zum C, sogar über zwei verschiedene Wege:

  1. ganz einfach über die letzte FD B->C
  2. oder mithilfe der zweiten FD B->DA: Mit dem B bekommen wir das A, dann haben wir AB und können wieder die erste FD gehen, um das C zu erreichen.
Hier haben wir jetzt zwei Wege, einer reicht aber aus. Wir können also A weglassen, weil wir auch nur mit dem B zum C kommen. B können wir natürlich nicht auch noch weglassen, dann hätten wir nämlich eine leere linke Seite.

Die FDs sehen nach der Linksreduktion also so aus:

B->C
B->DA
D->AC
B->C

Rechtsreduktion

Natürlich kommt nach der Links- auch eine Rechtsreduktion. Die funktioniert im Prinzip gleich. Auch hier fragen wir uns für jedes Attribut rechts, ob wir dieses Attribut weglassen können, ohne die Aussage der FDs zu verändern. Im Gegensatz zur Linksreduktion muss man hier wirklich alle Attribute rechts betrachten; hier ist es durchaus möglich (und erlaubt), dass rechts eine leere Menge entsteht.

Wir betrachten also die erste FD aus der Linksreduktion

B->C

und fragen uns: "Kann ich C weglassen?". Also: "Komme ich mit dem B sonst noch irgendwie zum C?". Die Antwort ist: Ja, klar, zum Beispiel über die letzte FD. Also lassen wir das C rechts weg und unsere FDs sehen jetzt so aus:

B->∅
B->DA
D->AC
B->C

Nächste Frage: "Kann ich in der zweiten FD das D weglassen?". Natürlich nicht, man sieht nämlich sofort, dass rechts nirgendwo sonst ein D steht. Wie sollen wir dann sonst irgendwie anders da hin kommen? D bleibt also. Was ist mit dem A in der zweiten FD, können wir das wegreduzieren? Die Antwort ist: Ja! Es gibt nämlich noch einen anderen Weg, um vom B zum A zu kommen, nämlich über die dritte FD: mit dem B haben wir ja das D (zweite FD), und mit dem D erreichen wir das A (dritte FD). Aktuell sehen unsere FDs also so aus:

B->∅
B->D
D->AC
B->C

Bei der dritten FD kann nichts rechtsreduziert werden, bei der letzten FD können wir das C weglassen. Die Begründungen seien dem Leser überlassen :). Wir haben nach der Rechtsreduktion also diese FDs:

B->∅
B->D
D->AC
B->∅

α→∅ entfernen

Der dritte Schritt ist einfach: Wir löschen alle FDs, bei denen die rechte Seite leer ist. Übrig bleiben also:

B->D
D->AC

FDs zusammenfassen

Im letzten Schritt müssen wir FDs, die die gleiche linke Seite haben, zusammenfassen. Diesen Fall haben wir hier nicht, also sind wir fertig. Zusammenfassen heißt: Wenn wir z.B. die FDs A->BC und A->E hätten, würden wir diese zu A->BCE zusammenfassen.

Wir haben jetzt also die Kanonische Überdeckung unserer Beispiel-FDs bestimmt, nämlich

B->D
D->AC

Synthesealgorithmus

Mit dem Synthesealgorithmus können wir jedes beliebige Schema verlustlos und abhängigkeitsbewahrend in die 3NF überführen. Da unser Beispiel-Schema nur in der 1NF ist, machen wir das natürlich! Auch hier sind vier Schritte notwendig:

Kanonische Überdeckung bestimmen

Das haben wir gerade schon erledigt :). Zur Erinnerung, die kanonische Überdeckung für unser Beispiel ist

B->D
D->AC

Relationsschemata formen

Da unsere Relation nicht in 3NF ist, müssen wir diese in mehrere kleinere Relationen aufteilen, die dann jeweils in 3NF sein sollen. Zunächst entsteht aus jeder FD der kanonischen Überdeckung eine neue Relation, indem wir alle Attribute einer FD in eine Relation packen. Wir erhalten also zwei Relationen:

R1:={BD}
R2:={ACD}

Schema mit Schlüssel hinzufügen

Wenn keiner der Kandidatenschlüssel der ursprünglichen Relation in irgend einem der neuen Relationen enthalten ist, müssen wir nochmal eine neue Relation hinzufügen, die die Attribute von irgend einem Kandidatenschlüssel enthält (da sucht man sich dann einfach einen aus; niemals alle Kandidatenschlüssel hinzufügen!). Unser (einziger) Kandidatenschlüssel BE ist weder in R1 noch in R2 enthalten, somit fügen wir ein neues Schema R3 hinzu:

R1:={BD}
R2:={ACD}
R3:={BE}

Redundante Schemata eliminieren

Wenn ein Schema in einem anderen komplett enthalten ist, dann können wir das "kleinere" Schema entfernen. Diesen Fall haben wir hier nicht. Kurz ein Beispiel, wo man ein Schema eliminieren müsste: Wenn wir R1:={ABD} und R2:={AB} hätten, würden wir R2 streichen.

Unser Schema in 3NF besteht also aus den drei Relationen

R1:={BD}
R2:={ACD}
R3:={BE}

Schlüssel bestimmen

Wir wollen jetzt noch für jede neue Relation einen Primärschlüssel bestimmen und unterstreichen. Dazu müssen wir erstmal für jede Relation schauen, welche FDs in dieser Relation gelten. Zum Beispiel:

In R1:={BD} gilt:
B->D

Hier gilt B->D. Dies ist genau die erste FD der kanonischen Überdeckung (bzw. ein Teil der zweiten FD des ursprünglichen Schemas. Die FD B->DA ist nämlich nichts anderes als B->D und B->A. B->A gilt natürlich nicht, aber B->D offensichtlich schon).

Jetzt haben wir eine Relation mit FDs und können ganz normal wie die (Kandidaten-)Schlüssel bestimmen. R1 hätte hier den (einzigen) Kandidatenschlüssel B, den wir dann auch als Primärschlüssel wählen und entsprechend unterstreichen. Die Herleitung aller (Kandidaten-)Schlüssel der anderen beiden Relationen sei dem Leser überlassen. Hier das Endergebnis:

R1:={BD}
R2:={ACD}
R3:={BE}


Dekompositionsalgorithmus für BCNF

Mit dem Dekompositionsalgorithmus kann man ein Schema verlustlos (aber nicht unbedingt abhängigkeitsbewahrend!) in die BCNF überführen. Dazu sucht man sich eine FD, die die BCNF verletzt, und teilt die Relation Ri anhand dieser FD (bezeichnen wir die FD mal als α->β) in zwei neue Relationen folgendermaßen auf:

Ri1 = α ∪ β
Ri2 = Ri - β

Für diese neuen Relationen überprüft man wiederum die Normalform und teilt sie wieder auf, sofern sie nicht in BCNF sind.

In unserem Beispiel verletzt z.B. die erste FD AB->C die BCNF (weder trivial noch steht links ein Superschlüssel). Wir wählen diese FD und spalten die Relation folgendermaßen auf:

R1:= {ABC}
R2:= {ABDE}

Die erste Relation erfüllt die BCNF (warum?), sodass wir die nicht weiter aufteilen müssen. In der zweiten Relation ist das aber nicht der Fall: hier verletzt z.B. die FD B->DA die BCNF (Kandidatenschlüssel in R2 ist BE, links steht also kein Superschlüssel und trivial ist die FD auch nicht). Also teilen wir R2 anhand von B->DA folgendermaßen auf:

R21:= {ABD}
R22:= {BE}

Jetzt schauen wir wieder ob die Relationen in BCNF sind. In der zweiten Relation gilt keine FD, also kann auch keine FD die BCNF verletzen, also das passt. R21 ist allerdings noch nicht in BCNF. In R21 gelten nämlich die FDs

B->DA
D->A

Kandidatenschlüssel ist also B, somit ist die erste FD okay (links Superschlüssel), die zweite aber nicht (links kein Superschlüssel, und nicht trivial). Also teilen wir R21 wieder auf. Das Ergebnis ist dann

R211:= {AD}
R212:= {BD}

Jetzt sind wir fertig, beide Relationen sind in BCNF. Das Gesamtergebnis (also das komplette Schema in BCNF) ist also:

R1:= {ABC}
R22:= {BE}
R211:= {AD}
R212:= {BD}


Dekompositionsalgorithmus für 4NF

Der Dekompositionsalgorithmus für 4NF ist im Prinzip genau gleich wie der für BCNF, nur dass man jetzt eben MVDs statt FDs betrachtet (d.h. man denkt sich die FDs als MVDs und nimmt noch die "reinen" MVDs (im Beispiel C->>A) hinzu). Am Ende kommt in unserem Beispiel fast das gleiche Schema wie oben für BCNF raus, mit einem Unterschied: in R1 gilt ja die MVD, die wir jetzt neu betrachten (C->>A), und die ist in der Relation weder trivial noch steht links ein Superschlüssel. Im Gegensatz zu vorher sind wir hier also nicht fertig, sondern müssen R1 nochmal anhand C->>A splitten. Es entstehen die Relationen

R11:= {AC}
R12:= {BC}

In R11 gilt nur die MVD C->>A, somit ist der Kandidatenschlüssel AC. Die linke Seite ist also kein Superschlüssel, aber die MVD ist trivial (schau nochmal die geänderte Definition für "triviale MVDs" im Vergleich zu "triviale FDs" an!). Also ist R11 okay. R12 ist auch okay, da gilt nur B->C, also erfüllt diese FD (bzw. hier im Kontext diese MVD) sogar beide Bedingungen: links steht ein Superschlüssel (sogar der Kandidatenschlüssel selbst), und die MVD ist auch trivial.

Wichtig bei der Suche nach den geltenden MVDs für eine Relation ist auch folgendes: eine MVD lässt sich (im Gegensatz zur FD) nicht anhand der rechten Seite aufteilen. Die MVD A->>BC ist also nicht das selbe wie A->>B und A->>C!

Alle anderen Aufspaltungen sind wie oben bei der Transformation in BCNF, das Endergebnis in 4NF ist also:

R11:= {AC}
R12:= {BC}
R22:= {BE}
R211:= {AD}
R212:= {BD}


Jetzt nur noch üben

Das wars schon!

Am besten gleich üben:

DB->normalizer