Datenbankdesign – Von einer Tabelle zu vielen
Lernziele
- Sie können erklären, warum flache Tabellen problematisch sind und welche Vorteile die Normalisierung von Daten mit sich bringt.
- Sie können den Zweck von Primärschlüsseln und Fremdschlüsseln in einer relationalen Datenbank beschreiben.
- Sie kennen die drei Beziehungstypen 1:1, 1:n und n:m und können sie voneinander unterscheiden.
- Sie können darlegen, weshalb n:m-Beziehungen eine Verknüpfungstabelle benötigen, und deren Aufbau aufzeigen.
In den letzten Kapiteln haben Sie mit einer einzigen Tabelle gearbeitet – der flachen tracks-Tabelle mit über 114'000 Zeilen. Dabei sind Ihnen bereits Probleme aufgefallen: Duplikate, mehrere Künstler in einem Feld, redundante Daten. In diesem Kapitel lernen Sie, warum man Daten auf mehrere Tabellen aufteilt und wie man die Beziehungen zwischen diesen Tabellen gestaltet.
Das Problem: Alles in einer Tabelle
Erinnern Sie sich an Aufgabe 6 aus dem SELECT-Kapitel? Dort haben Sie nach «Blinding Lights» gesucht und festgestellt, dass derselbe Song mehrfach vorkommt – in verschiedenen Genres und auf verschiedenen Alben. Auch das Feld artists war problematisch: Bei Kollaborationen standen mehrere Künstler in einer einzigen Zelle (Ingrid Michaelson;ZAYN).
Das sind typische Symptome einer flachen Tabelle:
| Problem | Beispiel |
|---|---|
| Redundanz | Alle Audio-Eigenschaften von «Blinding Lights» (Tanzbarkeit, Energie, Tempo, ...) werden für jeden Eintrag wiederholt |
| Änderungs-Anomalie | Wenn sich die Popularität von «Blinding Lights» ändert, müsste man alle Duplikate aktualisieren |
| Lösch-Anomalie | Löscht man den letzten Song eines Albums, geht auch die Information über das Album verloren |
| Mehrfachwerte | Ingrid Michaelson;ZAYN in einem Feld – schlecht durchsuchbar und fehleranfällig |
Zum NachdenkenStellen Sie sich vor, Sie verwalten eine Schulbibliothek in einer einzigen Tabelle: Jede Zeile enthält Buchtitel, Autor, Verlag, Schüler, Ausleihdatum. Was passiert, wenn ein Schüler 10 Bücher ausleiht? Und wenn ein Buch von 30 Schülern gelesen wird?
Die Lösung: Daten aufteilen
Die Idee ist einfach: Jede Art von Information bekommt ihre eigene Tabelle. Statt alles in eine riesige Tabelle zu quetschen, erstellen wir separate Tabellen für Songs, Künstler, Alben und Genres – und verbinden sie über Beziehungen.
Diesen Prozess nennt man Normalisierung.
Primärschlüssel und Fremdschlüssel
Bevor wir über Beziehungen sprechen, brauchen wir zwei zentrale Begriffe:
Primärschlüssel (Primary Key) – Eine Spalte (oder Kombination von Spalten), die jede Zeile in einer Tabelle eindeutig identifiziert. Keine zwei Zeilen dürfen denselben Primärschlüssel haben.
Tabelle: artists
┌────────────┬──────────────────────┐
│ artist_id │ name │ ← artist_id ist der Primärschlüssel
├────────────┼──────────────────────┤
│ 1 │ The Weeknd │
│ 2 │ Ingrid Michaelson │
│ 3 │ ZAYN │
└────────────┴──────────────────────┘
Fremdschlüssel (Foreign Key) – Eine Spalte, die auf den Primärschlüssel einer anderen Tabelle verweist. So entstehen Verbindungen zwischen Tabellen.
Stellen wir uns vereinfacht vor, jeder Song hätte genau einen Künstler. Dann könnte man in der tracks-Tabelle einfach eine Spalte artist_id einfügen, die auf die artists-Tabelle verweist:
Tabelle: tracks Tabelle: artists
┌──────────┬─────────────────┬────────────┐ ┌────────────┬────────────┐
│ track_id │ track_name │ artist_id │─────►│ artist_id │ name │
├──────────┼─────────────────┼────────────┤ ├────────────┼────────────┤
│ A1 │ Blinding Lights │ 1 │ │ 1 │ The Weeknd │
│ A2 │ Starboy │ 1 │ │ 2 │ Daft Punk │
│ A3 │ Get Lucky │ 2 │ │ 3 │ ZAYN │
└──────────┴─────────────────┴────────────┘ └────────────┴────────────┘
▲
Fremdschlüssel
Die Spalte artist_id in tracks ist der Fremdschlüssel – sie verweist auf den Primärschlüssel der artists-Tabelle. So weiss die Datenbank: «Blinding Lights» und «Starboy» gehören beide zu The Weeknd (artist_id = 1), ohne dass der Name «The Weeknd» mehrfach gespeichert werden muss.
Warum IDs statt Namen?Man könnte die Tabellen auch über den Künstlernamen verknüpfen. Aber was passiert, wenn sich ein Künstler umbenennt? Mit einer ID muss man den Namen nur an einer Stelle ändern – in der
artists-Tabelle. Alle Verknüpfungen bleiben intakt.
Beziehungstypen
Wenn man eine Datenbank entwirft, muss man für jede Verbindung zwischen zwei Tabellen die Frage beantworten: Wie viele Einträge auf der einen Seite gehören zu wie vielen auf der anderen? Es gibt drei Grundtypen.
1:1 – Eins-zu-Eins
Jeder Eintrag auf der einen Seite gehört zu genau einem auf der anderen – und umgekehrt.
1:1 in der PraxisEine Person hat genau einen Reisepass, und jeder Reisepass gehört genau einer Person. Dieser Typ ist in der Praxis selten – oft fasst man die Daten dann einfach in eine Tabelle zusammen. In unserer Spotify-Datenbank kommt er nicht vor.
1:1-Beziehungen werden manchmal trotzdem verwendet, um:
- Selten benötigte Daten auszulagern (z.B. detaillierte Adressinformationen)
- Sicherheitsrelevante Daten zu trennen (z.B. Passwort-Hashes in eigener Tabelle)
Umsetzung: Ein Fremdschlüssel in einer der beiden Tabellen, der gleichzeitig eindeutig (UNIQUE) sein muss – so kann jede Person nur einen Pass haben.
1:n – Eins-zu-Viele
Ein Eintrag auf der einen Seite gehört zu mehreren auf der anderen, aber nicht umgekehrt. Das ist der häufigste Beziehungstyp.
Eine Klasse hat viele Schüler, aber jeder Schüler gehört zu genau einer Klasse. Weitere Beispiele:
| «Eins»-Seite | «Viele»-Seite | Beziehung |
|---|---|---|
| Verlag | Bücher | Ein Verlag hat viele Bücher |
| Kunde | Bestellungen | Ein Kunde hat viele Bestellungen |
| Ordner | Dateien | Ein Ordner enthält viele Dateien |
Spotify-BeispielStellen Sie sich vor, jeder Song wäre auf genau einem Album – dann wäre die Beziehung Album → Songs eine 1:n-Beziehung. Ein Album hat viele Songs, aber jeder Song gehört zu genau einem Album.
In der Realität ist das aber nicht der Fall: «Blinding Lights» erscheint auf dem Originalalbum und auf Compilations. Deshalb ist die Beziehung Songs ↔ Alben bei uns n:m (siehe unten).
Umsetzung: Ein Fremdschlüssel in der «Viele»-Tabelle, der auf die «Eins»-Tabelle zeigt. Im Beispiel oben hat jeder Schüler eine Spalte klasse_id, die auf seine Klasse in der Tabelle Klasse verweist.
n:m – Viele-zu-Viele
Einträge auf beiden Seiten können zu mehreren der anderen Seite gehören. Dieser Typ ist der interessanteste – und der komplexeste.
Das Entscheidende: n:m-Beziehungen brauchen immer eine zusätzliche Verknüpfungstabelle (engl. Junction Table). Warum? Weil man weder in der einen noch in der anderen Tabelle einen einzelnen Fremdschlüssel setzen kann – es gibt ja mehrere Verknüpfungen.
Woran erkennt man n:m?Stellen Sie sich die Frage in beide Richtungen:
- Kann ein Song mehrere Künstler haben? → Ja (Kollaborationen)
- Kann ein Künstler mehrere Songs haben? → Ja
Sobald die Antwort in beide Richtungen «mehrere» ist, brauchen Sie eine Verknüpfungstabelle.
Beispiel: Songs und Künstler in der Spotify-Datenbank
«To Begin Again» hat zwei Künstler (Ingrid Michaelson und ZAYN), und jeder dieser Künstler hat wiederum viele andere Songs. Die Verknüpfungstabelle track_artists speichert diese Zuordnungen:
| track_id | artist_id | position |
|---|---|---|
| 3Vn9... (To Begin Again) | 4217 (Ingrid Michaelson) | 1 |
| 3Vn9... (To Begin Again) | 5765 (ZAYN) | 2 |
Zusätzliche Spalten in VerknüpfungstabellenDie Verknüpfungstabelle kann auch eigene Spalten haben. Hier speichert
position, welcher Künstler der Hauptkünstler ist (Position 1) und welcher ein Feature-Gast. Diese Information gehört weder zum Song noch zum Künstler allein – sie beschreibt die Beziehung zwischen beiden.
Umsetzung: Eine dritte Tabelle (die Verknüpfungstabelle) mit zwei Fremdschlüsseln – einer zeigt auf die Songs, der andere auf die Künstler. Der Primärschlüssel besteht aus beiden Spalten zusammen, damit dieselbe Kombination nicht doppelt vorkommen kann.
Überblick: Die drei Beziehungstypen
| Typ | Beispiel | Umsetzung |
|---|---|---|
| 1:1 | Person ↔ Reisepass | Fremdschlüssel + UNIQUE |
| 1:n | Klasse ↔ Schüler | Fremdschlüssel in der «Viele»-Tabelle |
| n:m | Song ↔ Künstler | Eigene Verknüpfungstabelle |
Die Spotify-Datenbank normalisieren
Schauen wir uns jetzt an, wie unsere flache tracks-Tabelle in eine normalisierte Datenbank umgebaut wird. Dabei müssen wir zuerst ein paar wichtige Entscheidungen treffen.
Schritt 1: Welche Entitäten gibt es?
Wir identifizieren die verschiedenen «Dinge» in unseren Daten:
- Songs – mit ihren Audio-Eigenschaften
- Künstler – die die Songs spielen
- Alben – auf denen die Songs erscheinen
- Genres – denen die Songs zugeordnet sind
Jede Entität bekommt ihre eigene Tabelle.
Schritt 2: Welche Beziehungen bestehen?
Für jede Kombination stellen wir die Frage in beide Richtungen:
| Beziehung | Frage 1 | Frage 2 | Typ |
|---|---|---|---|
| Songs ↔ Künstler | Kann ein Song mehrere Künstler haben? Ja | Kann ein Künstler mehrere Songs haben? Ja | n:m |
| Songs ↔ Alben | Kann ein Song auf mehreren Alben sein? Ja | Kann ein Album mehrere Songs haben? Ja | n:m |
| Songs ↔ Genres | Kann ein Song mehrere Genres haben? Ja | Kann ein Genre mehrere Songs haben? Ja | n:m |
Alle drei Beziehungen sind n:m – also brauchen wir drei Verknüpfungstabellen.
Schritt 3: Duplikate bereinigen
Bevor wir die Tabellen befüllen können, müssen wir die Duplikate in den Rohdaten behandeln. Denn «Blinding Lights» existiert fünfmal in der flachen Tabelle:
| track_name | artist | album | genre | popularity |
|---|---|---|---|---|
| Blinding Lights | The Weeknd | After Hours | pop | 91 |
| Blinding Lights | The Weeknd | Best R&B Tunes | pop | 3 |
| Blinding Lights | The Weeknd | Autopilot | pop | 3 |
| Blinding Lights | The Weeknd | Halloween 2022 | pop | 0 |
| Blinding Lights | The Weeknd | Halloween Party 2022 | pop | 0 |
Wichtige Entscheidungen:
- Was ist ein Duplikat? Gleicher Titel + gleicher Hauptkünstler + ähnliche Dauer (±10 Sekunden). So bleiben echte Varianten (Live-Version, Remix) als separate Einträge erhalten.
- Welche Version behalten wir? Den Eintrag mit der höchsten Popularität – in der Regel das Original.
- Was passiert mit den Informationen der Duplikate? Die Album- und Genre-Zuordnungen werden gesammelt und über die Verknüpfungstabellen mit dem überlebenden Track verknüpft.
Schritt 4: Das Ergebnis
Aus der flachen Tabelle mit 89'741 Einträgen wird eine normalisierte Datenbank mit 7 Tabellen:
| Tabelle | Einträge | Beschreibung |
|---|---|---|
tracks | 81'663 | Songs mit Audio-Eigenschaften – jeder Song nur einmal |
artists | 29'832 | Künstler – jeder nur einmal |
albums | 46'590 | Alben – jedes nur einmal |
genres | 113 | Genres – jedes nur einmal |
track_artists | 112'127 | Verknüpfung Songs ↔ Künstler |
track_albums | 89'390 | Verknüpfung Songs ↔ Alben |
track_genres | 82'167 | Verknüpfung Songs ↔ Genres |
Vorher und nachher: «Blinding Lights»Vorher (flache Tabelle): 5 Zeilen für denselben Song – mit Redundanz bei allen Audio-Eigenschaften.Nachher (normalisiert): 1 Zeile in
tracks+ 5 Einträge intrack_albums+ 1 Eintrag intrack_genres. Keine redundanten Daten, und die Beziehungen sind sauber getrennt.
Aufgaben
Aufgabe 1: Beziehungstyp bestimmen
Bestimmen Sie für die folgenden Beispiele, ob es sich um eine 1:1-, 1:n- oder n:m-Beziehung handelt:
- Land ↔ Hauptstadt – Jedes Land hat genau eine Hauptstadt, und jede Hauptstadt gehört zu genau einem Land.
- Lehrer ↔ Klassen – Ein Lehrer unterrichtet mehrere Klassen, und jede Klasse wird von mehreren Lehrern unterrichtet.
- Mutter ↔ Kinder – Eine Mutter kann mehrere Kinder haben, aber jedes Kind hat genau eine (biologische) Mutter.
- Schüler ↔ Kurse – Ein Schüler besucht mehrere Kurse, und in jedem Kurs sitzen mehrere Schüler.
- Auto ↔ Nummernschild – Jedes Auto hat genau ein Nummernschild, und jedes Nummernschild gehört zu genau einem Auto.
Lösung
- 1:1 – Land ↔ Hauptstadt
- n:m – Lehrer ↔ Klassen (braucht eine Verknüpfungstabelle)
- 1:n – Mutter ↔ Kinder (Fremdschlüssel
mutter_idin der Kinder-Tabelle)- n:m – Schüler ↔ Kurse (braucht eine Verknüpfungstabelle, z.B.
kurs_teilnehmer)- 1:1 – Auto ↔ Nummernschild
Aufgabe 2: Verknüpfungstabelle entwerfen
Sie bauen eine Datenbank für eine Bibliothek. Es gibt Tabellen für buecher (mit buch_id, titel) und autoren (mit autor_id, name).
Ein Buch kann mehrere Autoren haben, und ein Autor kann mehrere Bücher geschrieben haben.
Welchen Beziehungstyp haben wir hier? Entwerfen Sie die Verknüpfungstabelle: Wie soll sie heissen, und welche Spalten braucht sie?
LösungEs ist eine n:m-Beziehung, also brauchen wir eine Verknüpfungstabelle. Sie könnte
buch_autorenheissen und enthält zwei Fremdschlüssel:
buch_id→ verweist aufbuecherautor_id→ verweist aufautorenDer Primärschlüssel besteht aus beiden Spalten zusammen (
buch_id+autor_id).
Aufgabe 3: Schema skizzieren
Ein Online-Shop hat folgende Anforderungen:
- Kunden können mehrere Bestellungen aufgeben
- Jede Bestellung enthält mehrere Produkte
- Jedes Produkt kann in mehreren Bestellungen vorkommen
Welche Tabellen brauchen Sie? Welche Beziehungstypen liegen vor? Skizzieren Sie das Schema (Tabellennamen und die wichtigsten Spalten).
LösungTabellen:
kunden(kunden_id, name, email)bestellungen(bestell_id, kunden_id, datum) → 1:n zu Kundenprodukte(produkt_id, name, preis)bestellung_produkte(bestell_id, produkt_id, menge) → n:m-VerknüpfungBeziehungen:
- Kunden ↔ Bestellungen: 1:n (ein Kunde hat viele Bestellungen, Fremdschlüssel
kunden_idinbestellungen)- Bestellungen ↔ Produkte: n:m (braucht Verknüpfungstabelle
bestellung_produkte)
Zusammenfassung
Was Sie gelernt haben
- Eine flache Tabelle führt zu Redundanz, Anomalien und schlecht durchsuchbaren Daten
- Durch Normalisierung teilt man Daten auf mehrere Tabellen auf
- Primärschlüssel identifizieren Zeilen eindeutig, Fremdschlüssel stellen Verbindungen her
- 1:1-Beziehungen: selten, oft in einer Tabelle zusammengefasst
- 1:n-Beziehungen: Fremdschlüssel in der «Viele»-Tabelle
- n:m-Beziehungen: eigene Verknüpfungstabelle mit zwei Fremdschlüsseln
- Die Spotify-Datenbank nutzt drei n:m-Beziehungen: Songs ↔ Künstler, Songs ↔ Alben, Songs ↔ Genres
Im nächsten Kapitel lernen Sie, wie Sie mit JOIN die normalisierten Tabellen dynamisch so zusammenführen, wie wir sie gerade brauchen – und dabei die Vorteile der sauberen Struktur nutzen können.