🧩Das relationale Modell

Daten stehen in Tabellen, Beziehungen entstehen nur über Werte – über Schlüssel. Auf dieser Idee von E. F. Codd (1970) beruhen alle SQL-Datenbanken.

📖Begriffe

Relation / Tabelle

Menge von Zeilen gleicher Struktur. Mathematisch eine Menge: keine Reihenfolge, keine Duplikate (SQL erlaubt Duplikate trotzdem).

Tupel / Zeile

Ein Datensatz, z. B. ein Buch.

Attribut / Spalte

Hat einen Namen und einen Datentyp (Domäne).

Primärschlüssel (PK)

Identifiziert jede Zeile eindeutig, nie NULL. Kann aus mehreren Spalten bestehen (positionen: bestell_id + buch_id).

Fremdschlüssel (FK)

Verweist auf den Schlüssel einer anderen (oder derselben) Tabelle. Die Datenbank verhindert Verweise ins Leere.

UNIQUE

Wert darf nur einmal vorkommen – anders als der PK sind NULLs erlaubt (mehrere NULLs gelten nicht als gleich).

🗺️ER-Diagramm des Buchladens

Krähenfuß-Notation: der Fuß markiert die „viele“-Seite (Fremdschlüssel), der Strich die „genau eine“-Seite. Mit der Maus über eine Tabelle fahren hebt ihre Beziehungen hervor.
✍️ autorenPKautor_idINTEGERnameTEXTlandTEXT ∅geburtsjahrINTEGER ∅📚 buecherPKbuch_idINTEGERtitelTEXTFKautor_idINTEGER ∅genreTEXT ∅jahrINTEGER ∅preisREAL ∅🧑‍🤝‍🧑 kundenPKkunde_idINTEGERnameTEXTstadtTEXT ∅UQemailTEXT ∅🧾 bestellungenPKbestell_idINTEGERFKkunde_idINTEGERdatumTEXT📦 positionenPKbestell_idINTEGERPKbuch_idINTEGERmengeINTEGER🗂️ kategorienPKkat_idINTEGERnameTEXTFKeltern_idINTEGER ∅👩‍💼 mitarbeiterPKma_idINTEGERnameTEXTrolleTEXTFKchef_idINTEGER ∅gehaltINTEGER ∅
PK PrimärschlüsselFK FremdschlüsselUQ eindeutig∅ darf NULL seinpositionen ist eine Verbindungstabelle für die n:m-Beziehung Bestellung ↔ Buch

🔑Schlüssel in Aktion

Die Beispieldatenbank läuft mit PRAGMA foreign_keys = ON. Probiere, die Regeln zu brechen – die Datenbank lehnt ab.

So ist die Tabelle definiert

CREATE TABLE buecher (
  buch_id INTEGER PRIMARY KEY,
  titel TEXT NOT NULL,
  autor_id INTEGER REFERENCES autoren(autor_id),
  genre TEXT,
  jahr INTEGER,
  preis REAL CHECK (preis > 0)
);

CREATE TABLE positionen (
  bestell_id INTEGER NOT NULL REFERENCES bestellungen(bestell_id),
  buch_id INTEGER NOT NULL REFERENCES buecher(buch_id),
  menge INTEGER NOT NULL CHECK (menge > 0),
  PRIMARY KEY (bestell_id, buch_id)
);
SQL-Engine wird geladen …

🏗️Normalisierung Schritt für Schritt

Ein Bestellschein wird von der unnormalisierten Form bis zur 3. Normalform umgebaut. Die Normalform jeder Tabelle wird aus den funktionalen Abhängigkeiten berechnet – nicht behauptet.

Ausgangslage: der Bestellschein

Problem: In der Spalte „buecher“ stehen mehrere Werte in einer Zelle (Wiederholungsgruppe). Man kann weder nach einem Titel filtern noch Mengen summieren, ohne Text zu zerlegen.
Lösung: 1NF: jede Zelle enthält genau einen (atomaren) Wert – eine Zeile pro Bestellposition.
Funktionale Abhängigkeiten
bestell_id → datum, kunde_idkunde_id → kunde_name, stadtbuch_id → titel, preisbestell_id, buch_id → menge
1 Tabelle(n)24 Zellen
Schritt 1 / 4 · Tasten ← →
bestellschein0NF
🔑 bestell_iddatumkunde_idkunde_namestadtbuecher
1012026-01-121Anna BergHamburg1× Nebel über Lund (12,99 €); 1× SQL für Neugierige (29,90 €)
1022026-01-152Ben SchulzBerlin2× Salz und Sterne (18,00 €)
1032026-02-031Anna BergHamburg1× Der Garten der Zahlen (24,90 €); 2× Kirschblüten im Schnee (15,00 €)
1042026-02-203Clara VogelMünchen1× SQL für Neugierige (29,90 €); 1× Datenflüsse (34,00 €); 1× Das Rätsel von Kyoto (13,90 €)

🎓Boyce-Codd-Normalform (BCNF)

Strenger als 3NF: Jede Determinante (linke Seite einer Abhängigkeit) muss ein Schlüssel sein.

Im Lesekreis betreut jede Leitung genau ein Genre, und jede Person hat pro Genre genau eine Leitung:

teilnehmer, genre → leitungleitung → genre

Schlüsselkandidaten (berechnet): {teilnehmer, genre}{teilnehmer, leitung}

Alle Attribute sind Teil eines Schlüssels → 3NF erfüllt. Aber leitung → genre hat keinen Schlüssel links → keine BCNF: dass Herr Weiß Krimis leitet, lässt sich nicht speichern, solange niemand teilnimmt.

Zerlegung ist verlustfrei, verliert aber die Abhängigkeit teilnehmer, genre → leitung (nicht mehr per Schlüssel prüfbar). Deshalb begnügt man sich in der Praxis oft mit 3NF.

lesekreis3NF
teilnehmergenreleitung
AnnaKrimiFrau Kurz
AnnaLyrikHerr Stern
BenKrimiFrau Kurz
BenLyrikFrau Lang
ClaraKrimiHerr Weiß
leitung_genreBCNF
leitunggenre
Frau KurzKrimi
Herr SternLyrik
Frau LangLyrik
Herr WeißKrimi
teilnehmer_leitungBCNF
teilnehmerleitung
AnnaFrau Kurz
AnnaHerr Stern
BenFrau Kurz
BenFrau Lang
ClaraHerr Weiß

🧭Merksätze

💡 1NF
Jede Zelle ein Wert. Keine Listen, keine Wiederholungsgruppen wie buch1, buch2, buch3.
💡 2NF
Nicht-Schlüssel-Spalten hängen vom ganzen Schlüssel ab – nur relevant bei zusammengesetzten Schlüsseln.
💡 3NF
… und von nichts anderem als dem Schlüssel. Keine Abhängigkeiten zwischen Nicht-Schlüssel-Spalten.
✅ Denormalisieren – bewusst
Für Auswertungen (Data Warehouse, Berichte) speichert man Daten manchmal absichtlich redundant, um JOINs zu sparen. Dann aber mit klarer Quelle der Wahrheit.