LU08b: Warum Fremdschlüssel bzw. mehrere Tabellen?
Ausgangslage
Naheliegend ist: Alles in eine Tabelle (Post + Autor + Kategorie). In echten Blogs (z. B. WordPress) führt das aber zu Wiederholungen, Fehlern und hohem Wartungsaufwand.
Wir bleiben beim Reiseblog-Beispiel von der letzten Seite We Travel The World Blog.
Beispiel: Alles in einer Tabelle (schlechte Idee)
-- Eine Tabelle für alles: Post + Autor + Kategorie (redundant!) CREATE TABLE blog_posts ( id INT AUTO_INCREMENT PRIMARY KEY, post_title VARCHAR(200) NOT NULL, post_content TEXT, author_name VARCHAR(100) NOT NULL, author_email VARCHAR(200) NOT NULL, category_name VARCHAR(100) NOT NULL, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP );
Daten einfügen (nur eine Kategorie pro Zeile möglich):
INSERT INTO blog_posts (post_title, post_content, author_name, author_email, category_name, created_at) VALUES ('Hasselt – 10 Highlights', 'Kurzguide: Die schönsten Ecken von Hasselt …', 'Martin Merten', 'martin@wetraveltheworld.de', 'Städtereise', '2025-05-07 10:15:00'), ('Utrecht – 10 Sehenswürdigkeiten', 'Cafés, Grachten und Restaurant-Tipps …', 'Martin Merten', 'martin@wetraveltheworld.de', 'Städtereise', '2025-06-05 09:30:00'), ('Lissabon – 8 Tipps zu den wichtigsten Sehenswürdigkeiten', 'Aussichtspunkte, Viertel und Highlights …', 'Caro Steig', 'caro@wetraveltheworld.de', 'Portugal', '2025-03-21 08:40:00');
Warum nur eine Kategorie pro Zeile? Komma-Listen wirken bequem, sind aber ungünstig:
- Unzuverlässiges Filtern. Suchen mit LIKE liefern leicht Teiltreffer/Varianten. Beispiel:
WHERE category_name LIKE '%Guinea%' trifft auch «Equatorial Guinea», «Guinea», «Guinea-Bissau» und «Papua New Guinea» – vier verschiedene Länder.
Besser: Pro Zeile eine Kategorie. Für mehrere Kategorien pro Post (N:M-Beziehung) verwenden wir eine Zwischentabelle post_category.
Auszug:
Probleme auf einen Blick:
- Redundanz: Autorname/E-Mail wiederholen sich bei mehreren Posts.
- Fehleranfällig: Kategorienamen können unterschiedlich geschrieben werden.
- Aufwendig: E-Mail-Wechsel eines Autors → alle Zeilen suchen und ändern.
- Nur eine Kategorie möglich: Idealerweise möchten wir aber mehrere Kategorien pro Blog-Post vergeben – z.B. beim Blog-Post «Utrecht – 10 Sehenswürdigkeiten»: Niederlande, Städtereise.
Tippfehler in Kategorie: sichtbare Folgen
Ein fehlender Buchstabe reicht: Städtereise vs. Stätdereise.
INSERT INTO blog_posts (post_title, post_content, author_name, author_email, category_name, created_at) VALUES ('Maastricht an einem Tag', 'Spaziergang, Restaurants, Altstadt …', 'Caro Steig', 'caro@wetraveltheworld.de', 'Stätdereise', '2025-06-12 11:05:00'); -- Tippfehler!
Direkte Folgen in Abfragen:
| Abfrage | Zweck | Effekt bei Tippfehler |
|---|---|---|
SELECT DISTINCT category_name FROM blog_posts ORDER BY category_name; | Kategorienliste (Navigation/Filter) | Liste zeigt zwei Einträge: Stätdereise und Städtereise. |
SELECT id, post_title FROM blog_posts WHERE category_name = 'Städtereise'; | Beiträge in „Städtereise“ | Der Datensatz mit Stätdereise (dt vertauscht) fehlt im Resultat. |
Teil-Update: uneinheitliche E-Mail
Nur eine von mehreren Zeilen eines Autors wird geändert → inkonsistente Daten.
UPDATE blog_posts SET author_email = 'martin.new@wetraveltheworld.de' WHERE id = 1; SELECT id, post_title, author_name, author_email FROM blog_posts WHERE author_name = 'Martin Merten';
Ergebnis:
| id | post_title | author_name | author_email |
|---|---|---|---|
| 1 | Hasselt – 10 Highlights | Martin Merten | martin.new@wetraveltheworld.de |
| 2 | Utrecht – 10 Sehenswürdigkeiten | Martin Merten | martin@wetraveltheworld.de |
Gleicher Autor, unterschiedliche E-Mail → Daten sind inkonsistent.
Beziehungen in relationalen Datenbanken (1:n, n:m, 1:1) – einfach erklärt6) → (9:02, de) Grundlagen zu PK/FK und warum wir Beziehungen brauchen; zeigt, wie man 1:n modelliert und warum n:m ohne Zwischentabelle nicht direkt geht.
Ausblick
Auf der nächsten Seite bauen wir genau dieses Mehrtabellen-Schema mit Fremdschlüsseln auf und füllen es mit den obigen Reiseblog-Beispieldaten.