Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
| Beide Seiten der vorigen Revision Vorhergehende Überarbeitung Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
| modul:m290_guko:learningunits:lu08:theorie:d_fk-alter-table [2025/10/17 01:34] – gkoch | modul:m290_guko:learningunits:lu08:theorie:d_fk-alter-table [2025/10/27 07:23] (aktuell) – gkoch | ||
|---|---|---|---|
| Zeile 1: | Zeile 1: | ||
| - | ====== LU08d – FKs per ALTER TABLE + Referenzaktionen ====== | + | ====== LU08d: FKs per ALTER TABLE + Referenzaktionen ====== |
| - | **Ziel:** Bereits bestehende Tabellen mit **ALTER TABLE** um Fremdschlüssel | + | **Ziel:** Bereits bestehende Tabellen mit **ALTER TABLE** um Fremdschlüssel |
| - | Voraussetzung: | + | **Voraussetzung: |
| - | ===== 0) ALTER TABLE – Überblick (Syntax) | + | ===== 0) ALTER TABLE – Spalte in bestehende Tabelle hinzufügen |
| - | Mit **ALTER TABLE** können | + | Mit **ALTER TABLE** können bestehende Tabellen |
| <WRAP box round center 80%> | <WRAP box round center 80%> | ||
| - | **Spalte hinzufügen** | + | **Spalte hinzufügen |
| <code sql> | <code sql> | ||
| ALTER TABLE table_name | ALTER TABLE table_name | ||
| - | | + | ADD COLUMN neue_spalte DATENTYP [AFTER bestehende_spalte]; |
| - | </ | + | |
| - | + | ||
| - | **Spalte umbenennen** | + | |
| - | <code sql> | + | |
| - | ALTER TABLE table_name | + | |
| - | RENAME COLUMN altname TO neuename; | + | |
| - | </ | + | |
| - | + | ||
| - | **Datentyp ändern** | + | |
| - | <code sql> | + | |
| - | ALTER TABLE table_name | + | |
| - | MODIFY COLUMN spalte NEUER_DATENTYP [NULL|NOT NULL] [DEFAULT ...]; | + | |
| - | </ | + | |
| - | + | ||
| - | **Spalte löschen** | + | |
| - | <code sql> | + | |
| - | ALTER TABLE table_name | + | |
| - | DROP COLUMN spalte; | + | |
| </ | </ | ||
| Zeile 37: | Zeile 19: | ||
| <code sql> | <code sql> | ||
| ALTER TABLE table_name | ALTER TABLE table_name | ||
| - | | + | ADD CONSTRAINT fk_name |
| - | FOREIGN KEY (fk_spalte) | + | FOREIGN KEY (neue_spalte) |
| - | REFERENCES parent_table(parent_pk) | + | REFERENCES parent_table(parent_pk) |
| - | [ON DELETE | + | ON DELETE RESTRICT|CASCADE|SET NULL |
| - | [ON UPDATE | + | ON UPDATE RESTRICT|CASCADE|SET NULL; |
| </ | </ | ||
| + | </ | ||
| - | **Fremdschlüssel/ | + | <WRAP center tip round 80%> |
| - | <code sql> | + | [[https:// |
| - | ALTER TABLE table_name | + | |
| - | DROP FOREIGN KEY fk_name; | + | |
| - | -- Namen via | + | |
| - | SHOW CREATE TABLE table_name; | + | |
| - | -- herausfinden. | + | |
| - | </code> | + | |
| </ | </ | ||
| - | + | ===== 1) SET NULL: Redaktor:in (editor_id) in posts ===== | |
| - | ===== 1) Optionalen Verweis | + | |
| Wir ergänzen in **posts** eine **optionale** verantwortliche Redaktor:in (**editor_id**) und verknüpfen sie mit **users**. | 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** | ||
| <WRAP box round center 80%> | <WRAP box round center 80%> | ||
| - | === 1.1 Spalte ergänzen und Beispielwerte setzen === | ||
| <code sql> | <code sql> | ||
| -- Spalte hinzufügen | -- Spalte hinzufügen | ||
| ALTER TABLE posts | ALTER TABLE posts | ||
| - | | + | ADD COLUMN editor_id INT NULL AFTER author_id; |
| - | -- Beispielwerte passend zu LU08c-Daten (user_id: 1=caro, 2=martin, 3=shaolin) | + | -- Shaolin wieder hinzufügen, |
| + | INSERT INTO users (username, email, display_name) | ||
| + | VALUES(' | ||
| + | |||
| + | -- 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 = 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 = 1 WHERE post_id = 2; -- Post #2: Editor = caro | ||
| - | UPDATE posts SET editor_id = NULL WHERE post_id = 3; -- Post #3: (noch) kein Editor | + | UPDATE posts SET editor_id = 4 WHERE post_id = 3; -- Post #3: Editor = shaolin |
| </ | </ | ||
| </ | </ | ||
| + | **1.2 Fremdschlüssel setzen – SET NULL beim Löschen** | ||
| <WRAP box round center 80%> | <WRAP box round center 80%> | ||
| - | === 1.2 Fremdschlüssel setzen (SET NULL beim Löschen) === | ||
| <code sql> | <code sql> | ||
| ALTER TABLE posts | ALTER TABLE posts | ||
| - | | + | ADD CONSTRAINT fk_posts_editor |
| - | FOREIGN KEY (editor_id) | + | FOREIGN KEY (editor_id) |
| - | REFERENCES users (user_id) | + | REFERENCES users (user_id) |
| - | ON DELETE SET NULL | + | ON DELETE SET NULL |
| - | ON UPDATE RESTRICT; | + | ON UPDATE RESTRICT; |
| </ | </ | ||
| </ | </ | ||
| - | <WRAP tip round 80%> | + | <WRAP tip round 80% center> |
| - | **Warum SET NULL?** Die Redaktor:in ist **optional**. Wird ein User gelöscht, soll der Post **nicht** | + | **Warum SET NULL?** Die Redaktor:in ist **optional**. Wird der zugehörige |
| </ | </ | ||
| - | + | **Test:** | |
| - | ===== 2) N: | + | < |
| - | Die Zuordnungstabelle | + | |
| - | + | ||
| - | <WRAP box round center | + | |
| - | === 2.1 FKs mit CASCADE hinzufügen (oder neu setzen) === | + | |
| <code sql> | <code sql> | ||
| - | -- Falls die FKs noch NICHT existieren: | + | -- Lösche User ' |
| - | ALTER TABLE post_category | + | DELETE |
| - | ADD CONSTRAINT fk_pc_post | + | |
| - | FOREIGN KEY (post_id) | + | |
| - | REFERENCES posts (post_id) | + | |
| - | ON DELETE CASCADE | + | |
| - | ON UPDATE CASCADE, | + | |
| - | ADD CONSTRAINT fk_pc_category | + | |
| - | FOREIGN KEY (category_id) | + | |
| - | | + | |
| - | ON DELETE | + | |
| - | ON UPDATE CASCADE; | + | |
| - | -- Falls bereits FKs ohne CASCADE existieren: | + | -- Kontrolle: editor_id des betroffenen Posts ist jetzt NULL |
| - | -- 1) Namen ermitteln | + | SELECT post_id, title, editor_id FROM posts ORDER BY post_id; |
| - | SHOW CREATE TABLE post_category; | + | |
| - | -- 2) Alte FKs löschen | + | |
| - | ALTER TABLE post_category | + | |
| - | DROP FOREIGN KEY < | + | |
| - | DROP FOREIGN KEY < | + | |
| - | -- 3) Obige ALTER-Anweisung erneut ausführen (mit CASCADE) | + | |
| </ | </ | ||
| </ | </ | ||
| - | ---- | ||
| - | ===== 3) Referenzaktionen – kurz & praxisnah ===== | ||
| - | <WRAP box round center 80%> | + | ===== 2) CASCADE: Kommentare zur posts (comments → posts) ===== |
| - | **RESTRICT** – schützt Elternzeilen | + | Wir fügen eine Kindtabelle |
| - | Eltern (z. B. **users**) können nicht gelöscht/ | + | |
| - | **Demo (soll fehlschlagen):** | + | **2.1 Tabelle anlegen |
| + | <WRAP box round center 80%> | ||
| <code sql> | <code sql> | ||
| - | DELETE FROM users WHERE username = ' | + | CREATE TABLE comments ( |
| + | comment_id | ||
| + | post_id | ||
| + | author | ||
| + | body TEXT NOT NULL, | ||
| + | created_at | ||
| + | FOREIGN KEY (post_id) | ||
| + | REFERENCES posts (post_id) | ||
| + | ON DELETE CASCADE | ||
| + | ON UPDATE CASCADE | ||
| + | ); | ||
| </ | </ | ||
| </ | </ | ||
| + | **2.2 Kurz befüllen** | ||
| <WRAP box round center 80%> | <WRAP box round center 80%> | ||
| - | **CASCADE** – räumt automatisch auf | ||
| - | Kindzeilen in **post_category** werden mitgelöscht, | ||
| - | |||
| - | **Demo:** | ||
| <code sql> | <code sql> | ||
| - | -- Post #2 löschen → zugehörige Mappings verschwinden automatisch | + | INSERT INTO comments (post_id, author, body, created_at) VALUES |
| - | DELETE FROM posts WHERE post_id | + | (2, 'Leser A', |
| - | + | (2, ' | |
| - | -- Prüfung: | + | (5, ' |
| - | SELECT * FROM post_category WHERE post_id = 2; | + | |
| </ | </ | ||
| </ | </ | ||
| - | <WRAP box round center 80%> | + | **2.3 Test (CASCADE in Aktion)** |
| - | **SET NULL** – Verweis wird auf NULL gesetzt | + | <WRAP box round center 80%> <code sql> |
| - | Kindzeile (hier: **posts**) bleibt erhalten, der optionale Verweis wird NULL. | + | -- Post #2 löschen |
| - | + | DELETE FROM posts WHERE post_id | |
| - | **Demo:** | + | |
| - | <code sql> | + | |
| - | -- Kategorie ' | + | |
| - | DELETE FROM categories | + | |
| - | -- featured_category_id wird NULL, Post bleibt bestehen | + | -- … die zugehörigen Kommentare sind automatisch weg: |
| - | SELECT | + | SELECT |
| - | FROM posts | + | |
| - | ORDER BY post_id; | + | |
| </ | </ | ||
| </ | </ | ||
| - | **Beispielresultat (Ausschnitt nach den Demos):** | + | < |
| - | < | + | **Warum hier CASCADE?** Kommentare ohne zugehörigen Post sind nutzlos. |
| - | ^ post_id ^ title ^ featured_category_id ^ | + | Mit **ON DELETE CASCADE** bleibt die Datenbank **konsistent** und **aufräumen** passiert automatisch. |
| - | | 1 | Die Schweiz ist zu teuer? … Davos & Klosters im Winter | 1 | | + | |
| - | | 3 | Usbekistan Rundreise Highlights – Die 12 besten … | 3 | | + | |
| </ | </ | ||
| - | <wrap lo> | ||
| - | ---- | ||
| - | ===== 4) Merksätze ===== | ||
| - | * **RESTRICT**: | ||
| - | * **CASCADE**: | ||
| - | * **SET NULL**: Kindzeile bleibt erhalten, FK-Spalte wird **NULL** (ideal für **optionale** Verweise). | ||
| - | <WRAP tip round 80%> | + | ===== 3) Zusammenfassung ===== |
| - | **Reihenfolge beim Nachrüsten von FKs: | + | |
| - | 1) **Daten prüfen/ | + | |
| - | 2) **ALTER TABLE** mit passenden Referenzaktionen setzen. | + | |
| - | 3) Verhalten mit kleinen Test-Löschungen/ | + | |
| - | </ | + | |
| - | <WRAP info round 80%> | + | |
| - | **Ausblick | + | * **CASCADE**: Kindzeilen werden bei Änderungen/ |
| - | </ | + | |