Dies ist eine alte Version des Dokuments!
LU08c: Tabellen mit Fremdschlüssel erstellen
Ziel: Wir verteilen die Daten wie bei WordPress auf mehrere Tabellen (users, posts, categories und die N:M-Zuordnung post_category) und setzen die Fremdschlüssel direkt beim Erstellen.
ERD (Überblick)
Wir gehen vom Schema aus dem Reiseblog-Beispiel aus:
Posts können mehreren Kategorien angehören (N:M). Die saubere Lösung ist eine Zwischentabelle post_category.
Das bauen wir später (s. LU08e: N:M-Beziehungen mit Zwischentabelle abbilden.
Fremdschlüssel: Grundsyntax
CREATE TABLE TABLE_NAME ( id INT AUTO_INCREMENT PRIMARY KEY, foreign_key_col INT NOT NULL, -- Datentyp muss zum referenzierten Primary Key (in der anderen Tabelle) passen FOREIGN KEY (foreign_key_col) REFERENCES parent_table(parent_pk) );
Wichtig: Die referenzierte Tabelle (parent_table) muss bereits existieren, sonst meldet MySQL/MariaDB einen Fehler.
Beispiel Reiseblog
1. Tabellen anlegen
Tabelle users
CREATE TABLE users ( user_id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(60) NOT NULL UNIQUE, email VARCHAR(191) NOT NULL UNIQUE, display_name VARCHAR(100) NOT NULL, registered_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP );
Tabelle posts
CREATE TABLE posts ( post_id INT AUTO_INCREMENT PRIMARY KEY, title VARCHAR(200) NOT NULL, featured_img VARCHAR(512), content TEXT, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, author_id INT NOT NULL, FOREIGN KEY (author_id) REFERENCES users (user_id) -- Foreign Key wird hier angelegt! );
Tabelle categories
CREATE TABLE categories ( category_id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100) NOT NULL, slug VARCHAR(120) NOT NULL UNIQUE -- z. B. 'schweiz', 'staedtereise' );
2. Beispieldaten einfügen
Für ausführliche Erklärung zum Einfügen von Daten in Tabellen via SQL schauen Sie in „LU07 - DML: Daten einfügen, ändern und löschen“ nach.
-- 1) Autor:innen INSERT INTO users (username, email, display_name) VALUES ('caro', 'caro@wetraveltheworld.de', 'Caro Steig'), ('martin', 'martin@wetraveltheworld.de', 'Martin Merten'), ('shaolin', 'shaolin@wetraveltheworld.de', 'Shaolin Tran'); -- 2) Kategorien INSERT INTO categories (name, slug) VALUES ('Städtereise', 'staedtereise'), ('Abenteuer', 'abenteuer'), ('Roadtrip', 'roadtrip'), ('Belgien', 'belgien'), ('Niederlande', 'niederlande'), ('Portugal', 'portugal'), ('Deutschland', 'deutschland'), ('Montenegro', 'montenegro'), ('Oman', 'oman'), ('USA', 'usa'); -- 3) Posts INSERT INTO posts (title, featured_img, content, created_at, author_id) VALUES ('Hasselt – 10 Highlights', 'https://wetraveltheworld.de/wp-content/uploads/2025/05/hasselt.jpg', 'Kurzguide: Die schönsten Ecken von Hasselt …', '2025-05-07 10:15:00', 2), -- Martin ('Utrecht – 10 Sehenswürdigkeiten', 'https://wetraveltheworld.de/wp-content/uploads/2025/06/utrecht.jpg', 'Cafés, Grachten und Restaurant-Tipps …', '2025-06-05 09:30:00', 2), -- Martin ('Lissabon – 8 Tipps zu den wichtigsten Sehenswürdigkeiten', 'https://wetraveltheworld.de/wp-content/uploads/2025/03/lissabon.jpg', 'Aussichtspunkte, Viertel und Highlights …', '2025-03-21 08:40:00', 1), -- Caro ('Maastricht an einem Tag', 'https://wetraveltheworld.de/wp-content/uploads/2025/06/maastricht.jpg', 'Spaziergang, Restaurants, Altstadt …', '2025-06-12 11:05:00', 1), -- Caro ('Montenegro Roadtrip – 10 Highlights', 'https://wetraveltheworld.de/wp-content/uploads/2025/06/montenegro.jpg', 'Bucht von Kotor, Durmitor, Tara-Schlucht …', '2025-06-11 14:22:00', 1), -- Caro ('Oman – Top 22 Highlights', 'https://wetraveltheworld.de/wp-content/uploads/2025/06/oman.jpg', 'Nizwa, Wadis, Wüste und Roadtrip-Tipps …', '2025-06-11 09:00:00', 1), -- Caro ('Chicago in 3 Tagen – 17 Highlights', 'https://wetraveltheworld.de/wp-content/uploads/2024/10/chicago.jpg', 'Riverwalk, The Bean, Museen und Skyline …', '2024-10-07 07:50:00', 2); -- Martin
Resultate (nach dem Einfügen):
Verknüpfung Tabelle users & posts (one-to-many)
Tabelle categories (wird später verknüpft)
3. Mehrere Tabellen abfragen
Wenn wir nur die Tabelle posts abfragen, sehen wir in der Spalte author_id «nur» die ID (Zahl) aus users.user_id. Möchten wir wissen, wer den Beitrag verfasst hat, müssen wir posts und users gemeinsam abfragen.
Das geht mit der bekannten SELECT-Schreibweise: Wir nennen nach FROM beide Tabellen (mit Kommas getrennt) und setzen in der WHERE-Klausel den Fremdschlüssel posts.author_id gleich dem Primärschlüssel users.user_id. Durch die Angabe von users.display_name AS author erhalten wir zusätzlich die Spalte mit dem gewünschten Anzeigenamen.
SELECT posts.post_id, posts.title, users.display_name AS author FROM posts, users WHERE posts.author_id = users.user_id ORDER BY posts.post_id;
Mögliches Resultat:
| post_id | title | author |
|---|---|---|
| 1 | Hasselt – 10 Highlights | Martin Merten |
| 2 | Utrecht – 10 Sehenswürdigkeiten | Martin Merten |
| 3 | Lissabon – 8 Tipps fürs erste Mal | Caro Steig |
| 4 | Maastricht an einem Tag | Caro Steig |
| 5 | Montenegro Roadtrip – 10 Highlights | Caro Steig |
| 6 | Oman – Top 22 Highlights | Caro Steig |
| 7 | Chicago in 3 Tagen – 17 Highlights | Martin Merten |
Ausblick: In LU09 formulieren wir Abfragen über mehrere Tabellen (u. a. Categories via post_category) strukturiert mit JOINs.

