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:c_fk-create-table [2025/10/19 21:02] – gkoch | modul:m290_guko:learningunits:lu08:theorie:c_fk-create-table [2025/11/05 11:23] (aktuell) – gkoch | ||
|---|---|---|---|
| Zeile 5: | Zeile 5: | ||
| ==== ERD (Überblick) ==== | ==== ERD (Überblick) ==== | ||
| Wir gehen vom Schema aus dem Reiseblog-Beispiel aus: | Wir gehen vom Schema aus dem Reiseblog-Beispiel aus: | ||
| - | {{ : | + | |
| + | {{ : | ||
| <WRAP tip round 80% center> | <WRAP tip round 80% center> | ||
| Posts können mehreren Kategorien angehören (N:M). Die saubere Lösung ist eine Zwischentabelle '' | Posts können mehreren Kategorien angehören (N:M). Die saubere Lösung ist eine Zwischentabelle '' | ||
| - | Das bauen wir später (s. LU08e: N: | + | Das bauen wir später (s. LU08e: N: |
| </ | </ | ||
| ===== Fremdschlüssel: | ===== Fremdschlüssel: | ||
| + | <WRAP center tip round 80%> | ||
| + | [[https:// | ||
| + | </ | ||
| + | |||
| <WRAP box round center 80%> | <WRAP box round center 80%> | ||
| <code sql> | <code sql> | ||
| Zeile 26: | Zeile 31: | ||
| ===== Beispiel Reiseblog ===== | ===== Beispiel Reiseblog ===== | ||
| + | |||
| + | <WRAP center tip round 80%> | ||
| + | [[https:// | ||
| + | </ | ||
| ==== 1. Tabellen anlegen ==== | ==== 1. Tabellen anlegen ==== | ||
| Zeile 135: | Zeile 144: | ||
| === Verknüpfung Tabelle users & posts (one-to-many) === | === Verknüpfung Tabelle users & posts (one-to-many) === | ||
| - | {{ : | + | {{: |
| - | === Tabelle categories (wird später verknüpft) === | + | === Tabelle categories (wird später |
| - | {{ : | + | {{: |
| + | ==== 3. Fremdschlüssel in Aktion (Standard: RESTRICT) ==== | ||
| + | Beim Setzen von Fremdschlüsseln überwacht MySQL/ | ||
| + | Bezogen auf unser Reiseblog-Beispiel: | ||
| + | Damit ist //users// die Elterntabelle und //posts// die Kindtabelle. Die Folge von '' | ||
| - | ==== 3. Mehrere Tabellen abfragen ==== | + | * Löschen eines Users ist blockiert, solange Posts auf diesen User verweisen. |
| - | Wenn wir nur die Tabelle //posts// abfragen, sehen wir in der Spalte // | + | * Ändern von '' |
| + | | ||
| - | Das geht mit der bekannten SELECT-Schreibweise: | + | Probieren Sie folgende Codesnippets |
| - | Durch die Angabe von //users.display_name AS author// erhalten wir zusätzlich die Spalte mit dem gewünschten Anzeigenamen. | + | |
| + | === Demo 1 – User ohne Posts löschen (erlaubt) === | ||
| <WRAP center box 80% round>< | <WRAP center box 80% round>< | ||
| - | SELECT posts.post_id, | + | DELETE |
| - | FROM posts, | + | WHERE username |
| - | WHERE posts.author_id | + | SELECT user_id, username FROM users; |
| - | ORDER BY posts.post_id; | + | |
| </ | </ | ||
| + | // | ||
| - | **Mögliches Resultat: | + | === Demo 2 – User mit Posts löschen (blockiert) === |
| - | + | <WRAP center box 80% round>< | |
| - | <WRAP center box 80% round> | + | DELETE FROM users |
| - | ^ post_id ^ title ^ author ^ | + | WHERE username = ' |
| - | | 1 | Hasselt – 10 Highlights | Martin Merten | | + | </ |
| - | | 2 | Utrecht – 10 Sehenswürdigkeiten | Martin Merten | | + | //Erwartete Fehlermeldung (sinngemäss):// |
| - | | 3 | Lissabon – 8 Tipps fürs erste Mal | Caro Steig | | + | <WRAP alert round 80% center> |
| - | | 4 | Maastricht an einem Tag | Caro Steig | | + | [23000][1451] Cannot delete or update a parent row: a foreign key constraint fails |
| - | | 5 | Montenegro Roadtrip – 10 Highlights | Caro Steig | | + | (travel_blog.posts, |
| - | | 6 | Oman – Top 22 Highlights | Caro Steig | | + | |
| - | | 7 | Chicago in 3 Tagen – 17 Highlights | Martin Merten | | + | |
| </ | </ | ||
| + | //Grund: In posts.author_id gibt es Kindzeilen (z.B. " | ||
| + | |||
| + | === Demo 3 – Unkritisches Attribut ändern (erlaubt) === | ||
| + | <WRAP center box 80% round>< | ||
| + | UPDATE users | ||
| + | SET username = ' | ||
| + | WHERE user_id = 2; -- OK: FKs verweisen auf user_id, nicht auf username | ||
| + | </ | ||
| + | |||
| + | === Demo 4 – Primärschlüssel ändern (blockiert) === | ||
| + | <WRAP center box 80% round>< | ||
| + | UPDATE users | ||
| + | SET user_id = 5 | ||
| + | WHERE user_id = 2; -- erwartet: Fehler (RESTRICT), da posts.author_id -> users.user_id | ||
| + | </ | ||
| + | // | ||
| + | |||
| + | === Demo 5 – Primärschlüssel ändern: Geht das? (ja) === | ||
| + | <WRAP center box 80% round>< | ||
| + | UPDATE categories | ||
| + | SET category_id = 11 | ||
| + | WHERE category_id = 10; -- USA → 11: funktioniert - Primary Keys dürfen geändert werden. | ||
| + | </ | ||
| + | |||
| + | === Warum ist das so? === | ||
| + | |||
| + | // | ||
| + | Änderungen an nicht referenzierten Spalten (z. B. '' | ||
| + | Ob eine Änderung blockiert oder mitgezogen (CASCADE) wird, hängt von der ON DELETE/ON UPDATE-Einstellung im FK ab. | ||
| <WRAP tip round 80% center> | <WRAP tip round 80% center> | ||
| - | **Ausblick:** In LU09 formulieren wir Abfragen über mehrere Tabellen | + | Merke: Fremdschlüssel geben Datensicherheit: |
| + | | ||
| + | * definieren klares Verhalten bei Löschen/Ändern (RESTRICT, CASCADE, SET NULL), | ||
| + | | ||
| </ | </ | ||
| + | <wrap lo> Ausblick: In **LU08d** fügen wir FKs per **ALTER TABLE** nachträglich hinzu und testen die Referenzaktionen **RESTRICT**, | ||