EMZETT.
Login

Kurz: Guter Entwurf ist wichtiger als schlaue Abfragen. Vorgehen:

Teil des Kurses SQL

Kapitel 14 von 15 im Kurs SQL (Abschnitt „Entwurf“). Mit Fortschritt, Quiz und Zertifikat auf der Lernseite.

Vom Problem zum Modell

Guter Entwurf ist wichtiger als schlaue Abfragen. Vorgehen:

  1. Entitäten finden (Dinge, über die du Daten speicherst): Kunde, Bestellung, Produkt
  2. Attribute bestimmen: Name, Preis, Datum
  3. Beziehungen festlegen: Kunde 1:n Bestellung, Bestellung n:m Produkt
  4. Schlüssel wählen und Tabellen anlegen

Als Skizze dient ein ER-Diagramm (Entity-Relationship).

Normalisierung

Normalisierung vermeidet Redundanz und Anomalien (Änderungs-, Lösch- und Einfügefehler).

Schlechte Tabelle (alles in einer):

bestell_idkundekunden_ortprodukte
1MiaBerlinMaus, Laptop
2MiaBerlinMonitor

Probleme: Kundenort mehrfach gespeichert (Änderung muss überall erfolgen), mehrere Werte in einer Zelle.

NormalformRegel
1NFJede Zelle enthält genau einen Wert (keine Listen), jede Zeile ist eindeutig
2NF1NF, und jedes Nichtschlüsselattribut hängt vom ganzen Schlüssel ab
3NF2NF, und kein Nichtschlüsselattribut hängt von einem anderen Nichtschlüsselattribut ab

Gemerkt als: “Die Daten hängen vom Schlüssel, dem ganzen Schlüssel und nichts als dem Schlüssel.”

Ergebnis

PRAGMA foreign_keys = ON;
CREATE TABLE kunden (id INTEGER PRIMARY KEY, name TEXT NOT NULL, ort TEXT);
CREATE TABLE produkte (id INTEGER PRIMARY KEY, name TEXT NOT NULL, preis REAL NOT NULL);
CREATE TABLE bestellungen (id INTEGER PRIMARY KEY, kunde_id INTEGER NOT NULL REFERENCES kunden(id), datum TEXT);
CREATE TABLE positionen (
    bestellung_id INTEGER REFERENCES bestellungen(id),
    produkt_id    INTEGER REFERENCES produkte(id),
    menge INTEGER NOT NULL CHECK (menge > 0),
    preis_bei_kauf REAL NOT NULL,
    PRIMARY KEY (bestellung_id, produkt_id)
);
 
INSERT INTO kunden VALUES (1, 'Mia', 'Berlin');
INSERT INTO produkte VALUES (1, 'Maus', 25.5), (2, 'Laptop', 999);
INSERT INTO bestellungen VALUES (1, 1, '2025-01-10');
INSERT INTO positionen VALUES (1, 1, 2, 25.5), (1, 2, 1, 999);
 
SELECT k.name, p.name AS produkt, po.menge, po.menge * po.preis_bei_kauf AS summe
FROM positionen po
JOIN bestellungen b ON b.id = po.bestellung_id
JOIN kunden k ON k.id = b.kunde_id
JOIN produkte p ON p.id = po.produkt_id;

Ausgabe:

name  produkt  menge  summe
----  -------  -----  -----
Mia   Maus     2      51.0
Mia   Laptop   1      999.0

Beachte preis_bei_kauf: Der Preis zum Kaufzeitpunkt wird bewusst kopiert, weil der Produktpreis sich später ändert. Das ist gewollte Denormalisierung.

Denormalisierung

Manchmal verletzt man Normalformen bewusst, z. B. für Berichte oder Lesegeschwindigkeit (Zwischensummen speichern). Wichtig ist, dass es eine bewusste Entscheidung ist.

Namens- und Stilregeln

  • Einheitlich benennen (snake_case, Einzahl oder Mehrzahl konsequent)
  • Fremdschlüssel nach dem Muster tabelle_id
  • Immer Primärschlüssel; sinnvolle Constraints
  • Zeitstempel erstellt_am, geaendert_am bei Bedarf
  • Keine Sonderzeichen oder reservierten Wörter (order, user, group)
  • Soft Delete (geloescht_am) statt hartem Löschen, wenn Historie zählt

Merke

  • Entitäten, Attribute, Beziehungen: erst planen, dann Tabellen bauen
  • 1NF bis 3NF vermeiden Redundanz und Anomalien
  • Verbindungstabellen lösen n:m-Beziehungen
  • Gezielte Denormalisierung ist erlaubt, wenn begründet
  • Konsistente Namensgebung erleichtert die Arbeit im Team

Übungsaufgabe

Entwirf das Schema für eine Bibliothek (Bücher, Autoren, Mitglieder, Ausleihen) in 3NF.

Quiz zur Selbstkontrolle

Weiter im Kurs

Zurück: JSON, Textsuche und moderne SQL-Funktionen

Weiter: Referenz und Spickzettel

Alle Kapitel: SQL im Überblick