====== LU08d: FKs per ALTER TABLE + Referenzaktionen ====== **Ziel:** Bereits bestehende Tabellen mit **ALTER TABLE** um Fremdschlüssel ergänzen und verstehen, was **RESTRICT**, **CASCADE** und **SET NULL** bewirken. **Voraussetzung:** Die Codebeispiele verwenden die Tabellen **users**, **posts**, **categories**, **post_category** inkl. Beispieldaten aus der vorherigen Seite. ===== 0) ALTER TABLE – Spalte in bestehende Tabelle hinzufügen ===== Mit **ALTER TABLE** können bestehende Tabellen geändert werden – also auch Fremdschlüssel hinzugefügt werden. **Spalte hinzufügen (generelle Syntax)** ALTER TABLE table_name ADD COLUMN neue_spalte DATENTYP [AFTER bestehende_spalte]; **Fremdschlüssel hinzufügen** ALTER TABLE table_name ADD CONSTRAINT fk_name FOREIGN KEY (neue_spalte) REFERENCES parent_table(parent_pk) ON DELETE RESTRICT|CASCADE|SET NULL ON UPDATE RESTRICT|CASCADE|SET NULL; [[https://www.youtube.com/watch?v=aaO2cUhN9zA|ON DELETE: NO ACTION, SET NULL, CASCADE, SET DEFAULT]]((Prof. Dr. Jens Dittrich – Big Data Analytics / YouTube)) -> (9:22, de) Referenzaktionen kompakt: was bei Löschen/Ändern passiert und wann welche Option sinnvoll ist. ===== 1) SET NULL: Redaktor:in (editor_id) in posts ===== Wir ergänzen in **posts** eine **optionale** verantwortliche Redaktor:in (**editor_id**) und verknüpfen sie mit **users**. **1.1 Spalte ergänzen und Beispielwerte setzen** -- Spalte hinzufügen ALTER TABLE posts ADD COLUMN editor_id INT NULL AFTER author_id; -- Shaolin wieder hinzufügen, falls gelöscht INSERT INTO users (username, email, display_name) VALUES('shaolin','shaolin@wetraveltheworld.de','Shaolin Tran'); -- Beispielwerte passend zu user_id: 1=caro, 2=martin, 3=shaolin UPDATE posts SET editor_id = 2 WHERE post_id = 1; -- Post #1: Editor = martin UPDATE posts SET editor_id = 1 WHERE post_id = 2; -- Post #2: Editor = caro UPDATE posts SET editor_id = 4 WHERE post_id = 3; -- Post #3: Editor = shaolin (wenn Shaolin bereits gelöscht wurde und neu hier hinzugefügt wurde, dann hat er jetzt user_id 4) **1.2 Fremdschlüssel setzen – SET NULL beim Löschen** ALTER TABLE posts ADD CONSTRAINT fk_posts_editor FOREIGN KEY (editor_id) REFERENCES users (user_id) ON DELETE SET NULL -- User gelöscht → Post bleibt, Verweis wird NULL ON UPDATE RESTRICT; -- Primärschlüssel von users bleibt stabil **Warum SET NULL?** Die Redaktor:in ist **optional**. Wird der zugehörige User gelöscht, soll der Post **nicht** verschwinden – der optionale Verweis fällt auf **NULL**. **Test:** -- Lösche User 'shaolin' (ist nur Editor, nicht Autor) DELETE FROM users WHERE username = 'shaolin'; -- Kontrolle: editor_id des betroffenen Posts ist jetzt NULL SELECT post_id, title, editor_id FROM posts ORDER BY post_id; ===== 2) CASCADE: Kommentare zur posts (comments → posts) ===== Wir fügen eine Kindtabelle **comments** hinzu. Jeder Kommentar gehört zu **genau einem** Post. Wird ein Post gelöscht, sollen die zugehörigen Kommentare **automatisch verschwinden**. **2.1 Tabelle anlegen (mit CASCADE)** CREATE TABLE comments ( comment_id INT AUTO_INCREMENT PRIMARY KEY, post_id INT NOT NULL, author VARCHAR(100) NOT NULL, body TEXT NOT NULL, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (post_id) REFERENCES posts (post_id) ON DELETE CASCADE -- Post gelöscht → zugehörige Kommentare automatisch löschen ON UPDATE CASCADE -- (optional) ändert sich die post_id, wird sie hier mitgeändert ); **2.2 Kurz befüllen** INSERT INTO comments (post_id, author, body, created_at) VALUES (2, 'Leser A', 'Toller Utrecht-Tipp!', '2025-06-05 11:00:00'), (2, 'Leserin B', 'Gute Café-Empfehlungen.', '2025-06-05 12:10:00'), (5, 'Reisefreund','Kotor war mein Highlight!', '2025-06-11 16:00:00'); **2.3 Test (CASCADE in Aktion)** -- Post #2 löschen … DELETE FROM posts WHERE post_id = 2; -- … die zugehörigen Kommentare sind automatisch weg: SELECT * FROM comments WHERE post_id = 2; -- → keine Zeilen **Warum hier CASCADE?** Kommentare ohne zugehörigen Post sind nutzlos. Mit **ON DELETE CASCADE** bleibt die Datenbank **konsistent** und **aufräumen** passiert automatisch. ===== 3) Zusammenfassung ===== * **RESTRICT**: Löschen/Ändern der Elternzeile **nur** möglich, wenn **keine** Kindzeilen verweisen (Standardverhalten; schützt Datenkonsistenz). * **CASCADE**: Kindzeilen werden bei Änderungen/Löschungen der Eltern **automatisch** mitgeändert oder gelöscht (optimal für Zwischentabellen). * **SET NULL**: Kindzeile bleibt, der **optionale** Verweis wird **NULL**.