Dritte Normalform - ein Nicht-Schlüssel-Attribut darf nicht von einem Schlüssel und einem anderen Nicht-Schlüssel abhängen

Die dritte Normalform (NF3) verlangt, daß bei allen in der Datenbank definierten Tabellen, die bereits in der zweiten Normalform sind, kein Attribut C existiert, das bereits funktional von einem Nicht-Schlüssel-Attribut B abhängt. Denn da das Attribut C zur Tabelle gehört, sollte es vom Primärschlüssel A dieser Tabelle voll funktional abhängig sein. A umfaßt nur ein Attribut, da die Tabelle bereits in der zweiten Normalform ist. Ist C jedoch zusätzlich vom Nicht-Schlüssel-Attribut B abhängig und ist das Nicht-Schlüssel-Attribut vom Primärschlüssel A abhängig, so ist die Folgerung A -> C zwingend. Das transitiv abhängige Attribut C und das Attribut B bilden eine neue, bislang noch nicht in einer eigenen Tabelle isolierte Relation. Diese kann aus der aktuellen Tabelle herausgezogen werden, in die aktuelle Tabelle wird nur noch Attribut B bzw. der Primärschlüssel der neu gebildeten Tabelle eingetragen.

Der Unterschied zur vollen funktionalen Abhängigkeit der zweiten Normalform besteht darin, daß es sich hier um eine zusätzliche Beziehung zwischen zwei Nicht-Schlüssel-Attributen handelt. Die Frage nach der zweiten Normalform lautet dagegen, ob ein Nicht-Schlüssel-Attribut vom gesamten Schlüssel oder nur von einem Teilschlüssel abhängt. Falls letzteres der Fall ist, wird das Attribut in eine bereits vorhandene Tabelle, in welcher der Teilschlüssel der Primärschlüssel ist, verschoben.

Betrachten Sie den folgenden Ausschnitt aus dem ursprünglichen Beispiel 2:

lfNrLiefer-NrDatumArtikel (E)LieferantEPZahlArtikel (V)EmpfängerEPZahl
12415.2.2003Hosen, blauFA Muster-Liefer GbR, Nürnberg39.9050
22415.2.2003Hose, braunFA Muster-Liefer GbR, Nürnberg39.9050

Zunächst ist offensichtlich, daß der Lieferant herausgezogen und die Adresse aufgesplittet wird. In die aktuelle Tabelle wird lediglich die Lieferanten-Nummer eingetragen. Dann können Artikel-Namen und Farbbezeichnungen in schmale, zweispaltige Tabellen bestehend aus Id und Begriff, ausgelagert werden. Dies erlaubt es, für die Eingabe Pulldown-Felder zu nutzen und vermeidet Fehler aufgrund von Rechtschreib-Problemen bei der Texteingabe. Die Tabelle sieht wie folgt aus:

lfNrLiefer-NrDatumArtikel-NrFarb-IdLieferanten-IdEPZahl

Es fällt auf, daß eine Lieferung, durchgeführt an einem Tag, aus mehreren Artikeln bestehen kann, so daß mehrere Zeilen dieselbe Liefer-Nummer und dasselbe Datum enthalten sowie sich auf einen Lieferanten beziehen. Besteht jede Lieferung nur aus einem Artikel, so ist die Spalte Liefer-Nr überflüssig und könnte entfernt bzw. durch 'lfNr' ersetzt werden. Besteht eine Lieferung aus mehreren Artikeln, so sind Datum und Lieferanten-Nummer abhängig von der Liefer-Nummer. Der Artikel, sein Einkaufspreis und die Artikel-Anzahl hängen jedoch nur vom Primärschlüssel dieser Zeile ab und unterscheidet sich von anderen Zeilen, die zu derselben Lieferung gehören. Also kann eine Tabelle gebildet werden, welche die Grunddaten jeder Lieferung enthält. Eine auf dieser basierende Detailtabelle 'Lieferdetails' beinhaltet pro Zeile eine Kombination aus Artikel, Farbe und Preis. Damit ergibt sich für die Lieferungen die folgende Aufteilung:

Tabelle tbl_Lieferungen:

Liefer-NrDatumLieferanten-Id

Tabelle tbl_Lieferdetails:

lfNr-DetailsLiefer-NrArtikel-NrFarb-NrEPZahl

Die detaillierte Betrachtung einzelner Liefer-Details führt zum Sichtbar-Werden von Wiederholungen, so daß ein neues 'Objekt' 'Bestell-Rahmendaten', 'Grundtatsachen einer Lieferung' identifiziert und in eine eigene Tabelle ausgelagert wird. Beachten Sie, daß dies nur dann gilt, falls tatsächlich eine Lieferung aus mehreren Artikeln besteht. Selbstverständlich sind Szenarien denkbar, in welchen dies nicht gilt - dann ist eine solche zusätzliche, eingeschobene Tabelle redundant.

Ein Beispiel mit partieller Abhängigkeit

Betrachten Sie die folgende denormalisierte Tabelle:

DatumStrasseHausEtageWohnungZählerStandMitarbeiter

Ein Mitarbeiter eines Strom- oder Gaslieferanten liest diverse Strom- oder Gaszähler ab. Zur Straßen-Id gehören viele Häuser, zu jedem Haus mehrere Etagen, zu jeder Etage mehrere Wohnungen. In jeder Wohnung befindet sich ein Zähler mit einer eindeutigen Nummer. Dessen Stand wird zu einem festgelegten Datum turnusgemäß von verschiedenen Mitarbeitern abgelesen.

Jede Zeile kann eindeutig durch die beiden Spalten Datum und Zählernummer identifiziert werden. Denn jeder Zähler wird an einem Tag höchstens einmal abgelesen. Damit bilden diese beiden Spalten den zusammengesetzten Primärschlüssel. Die Mitarbeiter-Id hängt natürlich von diesem Geschäftsvorfall der Zähler-Ablesung ab. Die Straße ist ein nur vom Zähler, nicht vom Datum abhängiges Attribut. Denn von der Zählernummer ausgehend ist die Straße über die Wohnung, Etage und das Haus festgelegt. Zum Erreichen der zweiten Normalform werden deshalb Wohnung, Etage, Haus und Straße herausgezogen, all diese Werte sind durch die Zähler-Id festgelegt. Bei der zweiten Normalform ergibt sich damit die folgende Tabelle:

DatumZählerStandMitarbeiter

Werden in diese Tabelle viele Zeilen eingetragen, so wird eine zusätzliche Regelmäßigkeit sichtbar: Ein Mitarbeiter sammelt an einem Tag Informationen von allen Häusern einer Straße. Die Spalte Mitarbeiter ist also bereits determiniert durch die Kombination aus Datum und Hausnummer und wird bsp. im Rahmen einer Arbeitsverteilung in voraus festgelegt. Oder die Mitarbeiter sind von vornherein Ablesebereichen zugeteilt, so daß - unabhängig vom Datum - bekannt ist, welcher Mitarbeiter für die Ablesung innerhalb eines Intervalls zuständig ist. Im datumsfreien Fall gilt also die folgende transitive Abhängigkeit:

Zähler ―> Straße ―> Mitarbeiter

Hier kann das Attribut 'Mitarbeiter' zur Tabelle 'Straße' hinzugefügt und aus der aktuellen Tabelle entfernt werden. Für diese Straße ist jener Mitarbeiter zuständig. Bei der Version mit Datum gilt:

Zähler ―> Straße
Datum + Straße―> Mitarbeiter

Hier gibt es eine neue Tabelle mit Straßen-Id und Datum als Primärschlüssel sowie der Mitarbeiter-Id als Nicht-Schlüssel-Attribut. Die Straße darf nicht zur normalisierten Tabelle mit Datum, Zähler und Zählerstand hinzugenommen werden, weil sie vom Zähler voll funktional abhängig ist. Die restlichen Spalten werden gemäß der 1:n - Beziehung kanonisch normalisiert, so daß sich insgesamt die folgende Tabellenstruktur ergibt:

Strassen-IdOrtNameweitere für Straßen typische Eigenschaften

Haus-IdStrassen-IdHausnummerweitere für Häuser typische Eigenschaften

Etagen-IdHaus-IdEtagennummerweitere für Etagen typische Eigenschaften

Wohnungs-IdEtagen-IdHauptmieterweitere für Wohnungen typische Eigenschaften

Zähler-IdWohnungs-IdWerksnummer - 10-stellig mit Buchstabenweitere für Zähler typische Eigenschaften

Die neu identifizierte Tabelle mit Datum und Straßen-Id als Primärschlüssel:

DatumStraßen-IdMitarbeiter

Die Tabelle mit den eigentlichen Ablesedaten sieht nun wie folgt aus:

DatumZähler-IdZählerstandBemerkungen

Erläuterungen zum Verhältnis zwischen der zweiten und der dritten Normalform

Die Notwendigkeit der ersten Normalform dürfte den meisten Lesern unmittelbar einleuchten. Die Forderung nach dem Erfüllen der zweiten und der dritten Normalform bzw. nach dem Unterschied zwischen beiden Normalformen dürfte dagegen eher irritieren, da es sich hierbei um relativ stark mathematisch geprägte Konzepte handelt. Es folgen deshalb einige erläuternde Bemerkungen.

© 2003-2018 Jürgen Auer, Berlin.