dns Normalisierung von Datenbanken
Druckansicht schließen

Ziel der Normalisierung?

Das Ziel der Normalisierung ist, dass Daten redundanzfrei gespeichert werden. Um dies zu erreichen, werden im Normalisierungsprozess schrittweise feste Regeln angewendet, um die Struktur einfacher und geordneter zu gestalten. chat_bubble_outline Wenn eine Datenbank schlecht aufgebaut ist, wird es die Pflege und Weiterentwicklung deutlich erschweren.

Beispiel

Nehmen wir beispielsweise diesen Auszug aus einer Tabelle mit Reparaturaufträgen in einer Werkstatt, in der mehrere Mechaniker arbeiten:

Tabelle: Aufträge

Datum Kennzeichen Automarke Modell KdNr. Kunde MNr. Mechaniker Dienstleistungen Beendet
16.3.2018 MK:KI 163 Volvo 850 K101 Kiwits M01 Meinecke D801: Scheinwerfer reparieren,
D401: Bremsen kontrollieren
Ja
4.5.2018 MS:KU 458 Ford Mondeo K102 Kurze M02 Münz D106: Ausbeulen Ja
5.5.2018 DO:KL 558 VW Golf K103 Klein M02 Münz D408: Batterie wechseln Nein
8.6.2018 MK:KI 163 Volvo 750 K101 Kiwits M03 Maler D402: Bremsen erneuern Nein
9.6.2018 MK:KL 96 Opel Astra K103 Klein M03 Maler D002: Ölwechsel Nein

Probleme dieser Tabelle

Dies ist eine Tabelle, wie man sie sich gut im Archiv der Werkstatt vorstellen kann. Allerdings können mit dieser Relation einige Probleme entstehen:

Nicht zugelassener Datentyp: Der erste Auftrag besteht aus zwei Positionen. Nehmen wir an, die Mechanikerin repariert den Scheinwerfer, macht dann aber Feierabend und will den Rest morgen erledigen. Sie hat aber keine Möglichkeit, in der Tabelle zu erfassen, dass (nur) eine der beiden Positionen erfüllt ist. chat_bubble_outline

Einfügeanomalie: Man kann erkennen, dass der Kunde Kiwits seine Bremsen in einem neuen Auftrag erneuern lässt, nachdem sie einige Monate zuvor kontrolliert wurden. Allerdings scheint der Kunde nun mit einem neuen Auto mit exakt dem selben Kennzeichen angekommen zu sein. Wahrscheinlicher ist, dass einer der Mechaniker sich beim Modell vertan hat. chat_bubble_outline

Änderungsanomalie: Nehmen wir an, der Mechaniker Münz heiratet und nimmt den Namen seiner Frau an. Im Sinne der korrekten Datenhaltung müsste man nun alle Aufträge durchgehen und seinen Namen ändern. Ansonsten wüsste eine neue Kollegin nicht, wer Aufträge bearbeitet hat, falls das Auto noch einmal in der Werkstatt sein sollte. chat_bubble_outline

Löschanomalie: Angenommen, Mitarbeiter Münz will gerade eine neue Batterie in den Golf einsetzen, bemerkt dann aber, dass sich nur ein Kontakt gelöst hatte. Als ehrlicher Mitarbeiter informiert er den Kunden sofort und will den Auftrag stornieren. Er kann die Zeile allerdings nicht einfach löschen, ohne dass auch die Informationen über diesen Neukunden verloren gehen. chat_bubble_outline

Um diese Probleme zu beheben, werden wir nun nach und nach diese Tabelle normalisieren.

chevron_right Erste Normalform

Erste Normalform

Ziel der ersten Normalform ist es, nur zugelassene Datentypen in einzelnen Feldern zu speichern. Dies verhindert in erster Linie, dass keine Listen mehr in einzelnen Feldern vorhanden sind, wie es in unserer Beispieltabelle in der Spalte für Aufträge der Fall gewesen ist.

Tabelle: Aufträge

Datum Kennzeichen Automarke Modell KdNr. Kunde MNr. Mechaniker Dienstleistungen Beendet
16.3.2018 MK:KI 163 Volvo 850 K101 Kiwits M01 Meinecke D801: Scheinwerfer reparieren, D401: Bremsen kontrollieren Ja
priority_high Erste Normalform

„Eine Tabelle befindet sich in der 1. Normalform (1NF), wenn alle Attribute nur einfache Attributwerte aufweisen, wobei auch Nullwerte zulässig sind.“ chat_bubble_outline

Einfache Attributwerte können sein: Ein Text, eine Zahl, ein Datum, ein Boolean. chat_bubble_outline Mit einem Nullwert ist lediglich gemeint, dass ein Feld leer ist, also keinen Wert enthält.

Überführung in die 1NF

Um die Beispieltabelle in die 1NF zu überführen, betrachtet man die Felder, die Aufzählungen enthalten. Für jeden dieser Werte wird eine eigene Zeile der Tabelle erstellt. Ebenso kann es vorkommen, dass man einen Wert in zwei unterteilen kann. In unserem Beispiel ist ein Kürzel für die Dienstleistungen zusammen mit der Formulierung vorhanden. Diese werden in zwei Attribute unterteilt. Ein weiteres häufig auftretendes Beispiel ist es, ein gemeinsames Attribut für Vor- und Nachnamen zu nutzen. Im Sinne der 1NF sollte man diese separieren. chat_bubble_outline

Tabelle: Aufträge

Datum Kennzeichen Automarke Modell KdNr. Kunde MNr. Mechaniker DNr. Dienstleistungen Beendet
16.3.2018 MK:KI 163 Volvo 850 K101 Kiwits M01 Meinecke D801 Scheinwerfer reparieren Ja
16.3.2018 MK:KI 163 Volvo 850 K101 Kiwits M01 Meinecke D401 Bremsen kontrollieren Ja
chevron_right Schlüssel und Abhängigkeiten

Schlüssel und Abhängigkeiten

Bevor wir zu den zwei weiteren Normalformen gelangen, ist es zunächst erforderlich, einige Begrifflichkeiten zu verstehen, darunter die verschiedenen Schlüssel und Abhängigkeiten.

Schlüsselkandidaten und Primärschlüssel

Je nach Definition gehört es schon zur 1NF, einen Primärschlüssel zu erstellen chat_bubble_outline . Dieser dient der eindeutigen Identifizierung eines Eintrages der Tabelle. Spätestens bei der zweiten Normalform sollte man sich das Konzept von Primär- und Fremdschlüsseln zu eigen gemacht haben.

Um diese Beispiel nutzen zu können, gehen wir vereinfacht davon aus, dass Kennzeichen und Auto fest zusammenhängen. Wenn ein Auto also einmal ein Kennzeichen bekommen hat, ändert sich dies nicht mehr und auch, wenn das Auto schon verschrottet wurde, wird das Kennzeichen nicht anderweitig vergeben.

Zunächst bestimmen wir die verschiedenen Schlüsselkandidaten.

priority_high Schlüsselkandidat

Ein Schlüsselkandidat ist eine minimale Menge von Attributen, mit denen jeder Eintrag in einer Datenbanktabelle eindeutig identifiziert werden kann. chat_bubble_outline

Dabei ist nicht nur von den tatsächlich vorliegenden Werten auszugehen, sondern von allen weiteren denkbaren Einträgen. Man könnte auf die Idee kommen, dass die D-Nr. schon als Primärschlüssel ausreicht, da sie in der Tabelle immer eindeutig ist. Allerdings ist dies die ID für die Dienstleistungen, die vorgenommen werden sollen. Soll also bei einem zweiten Auto ein Ölwechsel vorgenommen werden, ist das Feld nicht mehr eindeutig. Man erkennt schnell: Zum Identifizieren der Schlüsselkandidaten benötigt man genaue Kenntnisse der Umstände.

In der Praxis ist es ein häufiges Vorgehen, einen künstlichen Schlüssel hinzuzufügen, der etwa eine aufsteigende Nummerierung der Einträge enthält. chat_bubble_outline In unserem Beispiel ist dieses Vorgehen allerdings nicht notwendig.

Mögliche Schlüsselkandidaten sind:

  • Datum, Kennzeichen, D-Nr.
  • Datum, Kennzeichen, Dienstleistung
  • Datum, Kennzeichen, Auftrag, Beendet

Hat man alle Schlüsselkandidaten identifiziert, liegt es an der Person, welche die Datenbank normalisiert, sich für einen Primärschlüssel zu entscheiden. Dies kann nach subjektiven Kriterien geschehen, allerdings sollte man einen möglichst kleinen Schlüssel wählen, dessen Attribute sich möglichst nicht mehr ändern sollten. chat_bubble_outline

priority_high Primärschlüssel

Der Primärschlüssel einer Tabelle ist ein beliebig gewählter Schlüsselkandidat. chat_bubble_outline

In diesem Fall entscheiden wir uns für die Kombination Datum, Kennzeichen und D-Nr. Die Überschriften aller Attribute, die Teil des Primärschlüssels sind, werden in der Regel unterstrichen dargestellt. chat_bubble_outline

Tabelle: Aufträge

Datum Kennzeichen Automarke Modell KdNr. Kunde MNr. Mechaniker DNr. Dienstleistungen Beendet
16.3.2018 MK:KI 163 Volvo 850 K101 Kiwits M01 Meinecke D801 Scheinwerfer reparieren Ja
16.3.2018 MK:KI 163 Volvo 850 K101 Kiwits M01 Meinecke D401 Bremsen kontrollieren Ja
4.5.2018 MS:KU 458 Ford Mondeo K102 Kurze M02 Münz D106 Ausbeulen Ja
5.5.2018 DO:KL 558 VW Golf K103 Klein M02 Münz D408 Batterie wechseln Nein
8.6.2018 MK:KI 163 Volvo 750 K101 Kiwits M03 Maler D402 Bremsen erneuern Nein
9.6.2018 MK:KL 96 Opel Astra K103 Klein M03 Maler D002 Ölwechsel Nein

Attribute, die zu keinem Schlüsselkandidaten gehören, werden auch Nichtschlüsselattribute genannt. chat_bubble_outline

Funktionale und transitive Abhängigkeit

Zur Überprüfung der zweiten und dritten Normalform untersucht man die Abhängigkeiten der Werte zueinander.

priority_high Funktionale Abhängigkeit

Eine Attributmenge A ist funktional abhängig von einer Attributmenge B, wenn jedem Wert von B genau ein Wert von A zugeordnet werden kann. chat_bubble_outline chat_bubble_outline

Folgende Beispiele für funktionale Abhängigkeiten sind in der Tabelle zu finden:

  • Der Kunde ist funktional abhängig vom Kennzeichen.
  • Die Dienstleistung ist funktional abhängig von der D-Nr.
  • Das Modell ist funktional abhängig von der Automarke.
  • Der Mechaniker ist funktional abhängig von Datum und Kennzeichen.
  • Der Mechaniker ist funktional abhängig von Datum, Kennzeichen und Automarke.
priority_high Vollfunktionale Abhängigkeit

Eine Attributmenge A ist vollfunktional abhängig von eine Attributmenge B, wenn A funktional abhängig ist von B, jedoch nicht von einer Teilmenge von B. chat_bubble_outline

Wir hatten bereits festgestellt, dass der Mechaniker funktional abhängig ist von Datum, Kennzeichen und Automarke. Jedoch ist diese Abhängigkeit nicht vollfunktional, weil eine Teilmenge existiert von der der Mechaniker abhängig ist – nämlich Datum und Kennzeichen. Von dieser Menge wiederum könnte man kein Attribut entfernen, ohne die funktionale Abhängigkeit zu verlieren. Somit gilt: Der Mechaniker ist vollfunktional abhängig von Datum und Kennzeichen. Mit diesen Definitionen schreiten wir nun weiter zur zweiten Normalform.

chevron_right Zweite Normalform

Zweite Normalform

priority_high Zweite Normalform

Eine Tabelle befindet sich in zweiter Normalform (2NF), wenn sie sich in erster Normalform befindet und jedes Nichtschlüsselattribut voll funktional von existierenden Schlüsselkandidaten abhängig ist. chat_bubble_outline chat_bubble_outline

Das Nichtschlüsselattribut ist somit abhängig von der Kombination aller Attribute der Schlüsselkandidaten, nicht nur von einer Teilmenge von ihnen. Wenn der einzige Schlüssel einer Tabelle in 1NF nur aus einem Attribut besteht, ist sie somit auch in 2NF. chat_bubble_outline

Werfen wir noch einmal einen Blick auf unsere Tabelle:

Tabelle: Aufträge

Datum Kennzeichen Automarke Modell KdNr. Kunde MNr. Mechaniker DNr. Dienstleistungen Beendet
16.3.2018 MK:KI 163 Volvo 850 K101 Kiwits M01 Meinecke D801 Scheinwerfer reparieren Ja
4.5.2018 MS:KU 458 Ford Mondeo K102 Kurze M02 Münz D106 Ausbeulen Ja

Hier kann man einige Attribute erkennen, bei denen das nicht der Fall ist:

  • Das Modell ist nicht vollfunktional abhängig vom Primärschlüssel, da es schon funktional abhängig vom Kennzeichen ist.
  • Die Dienstleistung ist ebenfalls nicht voll funktional abhängig, da sie bereits funktional abhängig von der D-Nr. ist.

Überführung in die 2NF

Um die Relation in die 2NF zu überführen, sind folgende Schritte notwendig: Für jedes Attribut A des Schlüssels, von dem Nichtschlüsselattribute N funktional abhängig sind, wird eine eigene Tabelle erstellt. In dieser neuen Tabelle ist A der Primärschlüssel. chat_bubble_outline

In unserem Beispiel besteht der Primärschlüssel aus drei Attributen:

  • Für das Datum existieren keine funktionalen Abhängigkeiten.
  • Für das Kennzeichen existieren die folgenden funktionalen Abhängigkeiten: Automarke, Modell, Kd-Nr., Kunde
  • Die Dienstleistung ist außerdem funktional abhängig von der D-Nr.

Das bedeutet, dass zwei neue Tabellen erstellt werden müssen. Die Nichtschlüsselattribute, die in die neue Tabelle überführt werden, werden aus der bestehenden Tabelle entfernt.

Tabelle: Aufträge

Datum Kennzeichen MNr. Mechaniker DNr. Beendet
16.3.2018 MK:KI 163 M01 Meinecke D801 Ja
16.3.2018 MK:KI 163 M01 Meinecke D401 Ja
4.5.2018 MS:KU 458 M02 Münz D106 Ja
5.5.2018 DO:KL 558 M02 Münz D408 Nein
8.6.2018 MK:KI 163 M03 Maler D402 Nein
9.6.2018 MK:KL 96 M03 Maler D002 Nein

Tabelle: Kunden

Kennzeichen Automarke Modell KdNr. Kunde
MK:KI 163 Volvo 850 K101 Kiwits
MS:KU 458 Ford Mondeo K102 Kurze
DO:KL 558 VW Golf K103 Klein
MK:KL 96 Opel Astra K103 Klein

Tabelle: Dienstleistungen

DNr. Dienstleistungen
D002 Ölwechsel
D106 Ausbeulen
D401 Bremsen kontrollieren
D402 Bremsen erneuern
D408 Batterie wechseln
D801 Scheinwerfer reparieren

Duplikate werden in den neu erstellten Tabellen selbstverständlich entfernt.

Diese Relation befindet sich nun in der zweiten Normalform.

In manchen Fällen kann es vorkommen, dass durch diesen Schritt Abhängigkeiten verloren gehen. Nähere Informationen dazu finden Sie beim Syntheseverfahren.

chevron_right Dritte Normalform

Dritte Normalform

Für die dritte Normalform untersucht man die Relation auf transitive Abhängigkeiten.

priority_high Transitive Abhängigkeit

Eine Attributmenge A ist transitiv abhängig von einer Attributmenge C, wenn A funktional abhängig ist von einer Attributmenge B und B wiederum funktional abhängig ist von C. chat_bubble_outline chat_bubble_outline

Ein synonym für die transitive Abhängigkeit wäre „indirekte Abhängigkeit“.

priority_high Dritte Normalform

Eine Tabelle befindet sich in dritter Normalform (3NF), wenn sie sich in zweiter Normalform befindet und kein Nichtschlüsselattribut transitiv abhängig ist von existierenden Schlüsselkandidaten. chat_bubble_outline

Im Beispiel existieren zwei Fälle:

Tabelle: Aufträge

Datum Kennzeichen MNr. Mechaniker DNr. Beendet
16.3.2018 MK:KI 163 M01 Meinecke D801 Ja

Tabelle: Autos

Kennzeichen Automarke Modell KdNr. Kunde
DO:KL 558 VW Golf K103 Klein
  • Der Mechaniker ist über die M-Nr. transitiv abhängig vom Primärschlüssel.
  • Der Kunde ist über die Kd-Nr. transitiv abhängig vom Primärschlüssel.

Die M-Nr. und Kd-Nr. werden in diesem Fall auch Determinanten genannt – durch sie existiert die transitive Abhängigkeit. chat_bubble_outline An dieser Stelle sei bemerkt, dass man die transitive Abhängigkeit auch andersherum identifizieren könnte, da es sich jeweils nur um einzelne Attribute (und nicht Attributmengen) handelt, die transitiv abhängig sind. In diesem Fall liegt es an der Person, die die Datenbank normalisiert, eine sinnvolle Lösung zu erkennen und zu verfolgen.

Überführung in die 3NF

Zur Wahrung der 3NF ist es notwendig, diese transitiven Abhängigkeiten aufzulösen. Auch hier werden die Abhängigkeiten in eine neue Tabelle überführt: Die transitiv abhängigen Attribute bilden zusammen mit der Determinante eine neue Tabelle. Nur die Determinante bleibt in der ursprünglichen Tabelle erhalten, in der neuen bildet sie den Primärschlüssel. chat_bubble_outline

Tabelle: Aufträge

Datum Kennzeichen MNr. DNr. Beendet
4.5.2018 MS:KU 458 M02 D106 Ja
5.5.2018 DO:KL 558 M02 D408 Nein
8.6.2018 MK:KI 163 M03 D402 Nein

Tabelle: Mechaniker

MNr. Mechaniker
M02 Münz
M03 Maler

Tabelle: Autos

Kennzeichen Automarke Modell KdNr.
MS:KU 458 Ford Mondeo K102
DO:KL 558 VW Golf K103
MK:KL 96 Opel Astra K103

Tabelle: Kunden

KdNr. Kunde
K102 Kurze
K103 Klein

An dieser Stelle sei angemerkt, dass die Tabellen mit Informationen über Mechaniker und Kunden in der Praxis deutlich größer ausfallen würden, an dieser Stelle wurde im Sinne der Übersichtlichkeit lediglich der Nachname angeführt.

chevron_right Syntheseverfahren

Syntheseverfahren

In einigen Fällen kann es vorkommen, dass bei der Normalisierung nach dem vorgestellten Algorithmus Abhängigkeiten verloren gehen. Für diesen Fall existiert das sogenannte Syntheseverfahren chat_bubble_outline , welches hier kurz vorgestellt werden soll.

Dazu betrachten wir eine leicht abgeänderte Tabelle als Beispiel:

Tabelle: Aufträge

Datum Kennzeichen KdNr. Kunde Kd. Alter MNr.
16.3.2018 MK:KI 163 K101 Kiwits 32 M01
4.5.2018 MS:KU 458 K102 Kurze 24 M02
8.6.2018 MK:KI 163 K101 Kiwits 33 M03

Diese Relation befindet sich schon in erster Normalform. Als Schlüsselkandidat kommt Datum, Kennzeichen infrage. Will man nun zur zweiten Normalform voranschreiten, würde man feststellen, dass KdNr. und Kunde voll funktional vom Kennzeichen abhängig sind und eine neue Tabelle erstellen, die dieses als Primärschlüssel enthält.

Tabelle: Aufträge

Datum Kennzeichen Kd. Alter MNr.
16.3.2018 MK:KI 163 32 M01
4.5.2018 MS:KU 458 24 M02
8.6.2018 MK:KI 163 33 M03

Tabelle: Kunden

Kennzeichen KdNr. Kunde
MK:KI 163 K101 Kiwits
MS:KU 458 K102 Kurze
MK:KI 163 K101 Kiwits

Problem der zweiten Normalform

An dieser Stelle geht allerdings eine Abhängigkeit verloren: Das Alter des Kunden (Kd. Alter) ist abhängig von den beiden Spalten Datum und KdNr., wünschenswert wäre deshalb eine solche Tabelle:

Tabelle: Kundenalter

Datum KdNr. Kd. Alter
16.3.2018 K101 32
4.5.2018 K102 24
8.6.2018 K101 33

Eine solche Tabelle wird sich allerdings nicht mehr ergeben. Das Alter des Kunden würde in der Auftragstabelle erhalten bleiben und dort nicht redundanzfrei abgespeichert werden. Dies ist allerdings der Zweck der Normalisierung.

Ein besseres Vorgehen

Bei Syntheseverfahren überlegt man sich nach der ersten Normalform – losgelöst von Schlüsselkandidaten –, welche Abhängigkeiten in der Relation existieren: chat_bubble_outline

  • Datum, Kennzeichen → MNr.
  • Kennzeichen → KdNr., Kunde
  • Datum, KdNr. → Kd. Alter

In dieser Überlegung taucht auch das oben genannte, wünschenswerte Beispiel auf. Für jede dieser Abhängigkeiten baut man eine Tabelle auf:

Tabelle: Mitarbeiter

Datum Kennzeichen MNr.
16.3.2018 MK:KI 163 M01
4.5.2018 MS:KU 458 M02
8.6.2018 MK:KI 163 M03

Tabelle: Kunden

Kennzeichen KdNr. Kunde
MK:KI 163 K101 Kiwits
MS:KU 458 K102 Kurze
MK:KI 163 K101 Kiwits

Tabelle: Alter des Kunden

Datum KdNr. Kd. Alter
16.3.2018 K101 32
4.5.2018 K102 24
8.6.2018 K101 33

Diese Relation befindet sich direkt in dritter Normalform. chat_bubble_outline

chevron_right Zusammenfassung