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:aufgaben:a_fk_in_lu05 [2025/10/19 23:44] – gkoch | modul:m290_guko:learningunits:lu08:aufgaben:a_fk_in_lu05 [2025/10/27 11:02] (aktuell) – gkoch | ||
|---|---|---|---|
| Zeile 17: | Zeile 17: | ||
| * Prüft, dass **Primärschlüssel vorhanden** sind (wie in LU05), aber **keine** Fremdschlüssel. | * Prüft, dass **Primärschlüssel vorhanden** sind (wie in LU05), aber **keine** Fremdschlüssel. | ||
| * Falls ihr neu starten wollt: erstellt die Tabellen nochmals wie in LU05 (PK ja, FK noch nicht) und füllt ein paar **Beispieldaten** ein (mind. 3 Zeilen pro Tabelle). | * Falls ihr neu starten wollt: erstellt die Tabellen nochmals wie in LU05 (PK ja, FK noch nicht) und füllt ein paar **Beispieldaten** ein (mind. 3 Zeilen pro Tabelle). | ||
| + | * PDF mit Schema zu den einzelnen Cases: {{ : | ||
| Zeile 32: | Zeile 33: | ||
| **SQL-Muster (anpassen): | **SQL-Muster (anpassen): | ||
| + | <WRAP center box round 80%> | ||
| + | 1. Erstellen Sie eine neue Spalte für den Fremdschlüssel: | ||
| <code sql> | <code sql> | ||
| - | ALTER TABLE < | + | ALTER TABLE TABLE_NAME |
| - | ADD CONSTRAINT fk_<kind>_<eltern> | + | ADD COLUMN neue_spalte DATENTYP [AFTER bestehende_spalte]; |
| - | FOREIGN KEY (< | + | </code> |
| - | REFERENCES | + | 2. Setzen Sie die soeben erstellte Spalte als Fremdschlüssel (Foreign Key): |
| + | <code sql> | ||
| + | ALTER TABLE kind_tabelle | ||
| + | ADD FOREIGN KEY (neue_spalte) | ||
| + | REFERENCES eltern_tabelle(primaerschluessel_spalte) | ||
| ON DELETE RESTRICT | ON DELETE RESTRICT | ||
| ON UPDATE RESTRICT; | ON UPDATE RESTRICT; | ||
| </ | </ | ||
| + | </ | ||
| <WRAP center box round 80%> | <WRAP center box round 80%> | ||
| Zeile 50: | Zeile 58: | ||
| - | ==== 3) DML testen – RESTRICT | + | ==== 3) DML testen – RESTRICT |
| - | **So gehst du vor (für euren gewählten Case):** | + | //DML = Data Manipulation Language -> Daten einfügen, ändern, löschen// |
| + | |||
| + | **So gehen Sie vor (für euren gewählten Case):** | ||
| - | 1. **Mini-Daten anlegen** | + | 1. **Daten anlegen** |
| 2. **Tests A–D** ausführen und das Verhalten beobachten (Kommentar sagt, was passieren soll). | 2. **Tests A–D** ausführen und das Verhalten beobachten (Kommentar sagt, was passieren soll). | ||
| - | > Hinweis: | + | > Hinweis: |
| - | --- | + | === Case: Tierheim (Tierart → viele Tiere) == |
| - | ### Case: Tierheim (»Tierart« | + | **FK:** // |
| - | **FK:** `tier.art_id` → `tierart.art_id` | + | **Daten** |
| - | + | ||
| - | **Mini-Daten** | + | |
| <WRAP center box 80% round>< | <WRAP center box 80% round>< | ||
| INSERT INTO tierart (art_id, bezeichnung) VALUES (1,' | INSERT INTO tierart (art_id, bezeichnung) VALUES (1,' | ||
| INSERT INTO tier (tier_id, name, geburtsdatum, | INSERT INTO tier (tier_id, name, geburtsdatum, | ||
| - | VALUES (101,' | + | VALUES (101,' |
| + | </ | ||
| **Tests A–D** | **Tests A–D** | ||
| Zeile 74: | Zeile 83: | ||
| -- A) INSERT: gültig vs. ungültig | -- A) INSERT: gültig vs. ungültig | ||
| INSERT INTO tier (tier_id, name, geburtsdatum, | INSERT INTO tier (tier_id, name, geburtsdatum, | ||
| - | VALUES (102,' | + | VALUES (102,' |
| INSERT INTO tier (tier_id, name, geburtsdatum, | INSERT INTO tier (tier_id, name, geburtsdatum, | ||
| - | VALUES (103,' | + | VALUES (103,' |
| -- B) DELETE Eltern mit Kind | -- B) DELETE Eltern mit Kind | ||
| - | DELETE FROM tierart WHERE art_id = 1; | + | DELETE FROM tierart WHERE art_id = 1; -- sollte scheitern (RESTRICT), weil Tier 101 darauf zeigt |
| -- C) UPDATE FK im Kind (umhängen) | -- C) UPDATE FK im Kind (umhängen) | ||
| Zeile 85: | Zeile 94: | ||
| -- D) UPDATE PK in Eltern | -- D) UPDATE PK in Eltern | ||
| - | UPDATE tierart SET art_id = 5 WHERE art_id = 2; -- sollte scheitern, solange Tiere auf 2 verweisen </ | + | UPDATE tierart SET art_id = 5 WHERE art_id = 2; -- sollte scheitern, solange Tiere auf 2 verweisen </ |
| + | </ | ||
| - | --- | ||
| - | ### Case: Postzustellung (»Postgebiet« | + | === Case: Postzustellung (Postgebiet |
| - | **FK: | + | **FK: |
| - | **Mini-Daten** | + | **Daten** |
| - | <WRAP center box 80% round>< | + | <WRAP center box 80% round> |
| + | <code sql> | ||
| INSERT INTO postgebiet (gebiet_id, name, plz_bereich) VALUES (10,' | INSERT INTO postgebiet (gebiet_id, name, plz_bereich) VALUES (10,' | ||
| (20,' | (20,' | ||
| Zeile 104: | Zeile 114: | ||
| -- A) INSERT | -- A) INSERT | ||
| INSERT INTO briefkasten (briefkasten_id, | INSERT INTO briefkasten (briefkasten_id, | ||
| - | VALUES (502,' | + | VALUES (502,' |
| INSERT INTO briefkasten (briefkasten_id, | INSERT INTO briefkasten (briefkasten_id, | ||
| - | VALUES (503,' | + | VALUES (503,' |
| -- B) DELETE Eltern | -- B) DELETE Eltern | ||
| Zeile 115: | Zeile 125: | ||
| -- D) UPDATE PK in Eltern | -- D) UPDATE PK in Eltern | ||
| - | UPDATE postgebiet SET gebiet_id = 11 WHERE gebiet_id = 20; | + | UPDATE postgebiet SET gebiet_id = 11 WHERE gebiet_id = 20; -- scheitert, solange Kinder auf 20 zeigen </ |
| - | --- | + | === Case: Online-Kleidershop (Kategorie → viele Kleidungsstücke) === |
| - | ### Case: Online-Kleidershop (»Kategorie« | + | **FK:** // |
| - | **FK:** `kleidungsstueck.kategorie_id` → `kategorie.kategorie_id` | + | **Daten** |
| - | + | ||
| - | **Mini-Daten** | + | |
| <WRAP center box 80% round>< | <WRAP center box 80% round>< | ||
| INSERT INTO kategorie (kategorie_id, | INSERT INTO kategorie (kategorie_id, | ||
| INSERT INTO kleidungsstueck (artikel_id, | INSERT INTO kleidungsstueck (artikel_id, | ||
| - | VALUES (9001,' | + | VALUES (9001,' |
| + | </ | ||
| **Tests A–D** | **Tests A–D** | ||
| Zeile 138: | Zeile 147: | ||
| -- B) DELETE Eltern | -- B) DELETE Eltern | ||
| - | DELETE FROM kategorie WHERE kategorie_id = 1; | + | DELETE FROM kategorie WHERE kategorie_id = 1; -- scheitert (RESTRICT), Schuh 9001 existiert |
| -- C) UPDATE FK im Kind | -- C) UPDATE FK im Kind | ||
| Zeile 144: | Zeile 153: | ||
| -- D) UPDATE PK in Eltern | -- D) UPDATE PK in Eltern | ||
| - | UPDATE kategorie SET kategorie_id = 5 WHERE kategorie_id = 2; -- scheitert bei referenzierten Zeilen </ | + | UPDATE kategorie SET kategorie_id = 5 WHERE kategorie_id = 2; -- scheitert bei referenzierten Zeilen </ |
| + | </ | ||
| - | --- | + | === Case: Eishockeyverein (Team → viele Blöcke) === |
| - | ### Case: Eishockeyverein (»Team« | + | **FK:** // |
| - | **FK:** `block.team_id` → `team.team_id` | + | **Daten** |
| - | + | ||
| - | **Mini-Daten** | + | |
| <WRAP center box 80% round>< | <WRAP center box 80% round>< | ||
| INSERT INTO team (team_id, name, altersklasse) VALUES (100,' | INSERT INTO team (team_id, name, altersklasse) VALUES (100,' | ||
| - | INSERT INTO block (block_id, bezeichnung, | + | INSERT INTO block (block_id, bezeichnung, |
| + | </ | ||
| **Tests A–D** | **Tests A–D** | ||
| - | <WRAP center box 80% round>< | + | <WRAP center box 80% round> |
| + | <code sql> | ||
| -- A) INSERT | -- A) INSERT | ||
| INSERT INTO block (block_id, bezeichnung, | INSERT INTO block (block_id, bezeichnung, | ||
| Zeile 164: | Zeile 174: | ||
| -- B) DELETE Eltern | -- B) DELETE Eltern | ||
| - | DELETE FROM team WHERE team_id = 100; -- scheitert (RESTRICT), Block 301 hängt dran | + | DELETE FROM team WHERE team_id = 100; -- scheitert (RESTRICT), Block 301 hängt dran |
| -- C) UPDATE FK im Kind | -- C) UPDATE FK im Kind | ||
| Zeile 170: | Zeile 180: | ||
| -- D) UPDATE PK in Eltern | -- D) UPDATE PK in Eltern | ||
| - | UPDATE team SET team_id = 250 WHERE team_id = 200; | + | UPDATE team SET team_id = 250 WHERE team_id = 200; -- scheitert, wenn Blocks auf 200 zeigen </ |
| + | </ | ||
| - | --- | ||
| - | ### Case: Öffentlicher Verkehr (»Linie« | + | === Case: Öffentlicher Verkehr (Linie → viele Fahrten) === |
| - | **FK: | + | **FK: |
| - | **Mini-Daten** | + | **Daten** |
| - | <WRAP center box 80% round>< | + | <WRAP center box 80% round> |
| + | <code sql> | ||
| INSERT INTO linie (linien_id, name, betreiber) VALUES (7,' | INSERT INTO linie (linien_id, name, betreiber) VALUES (7,' | ||
| INSERT INTO fahrt (fahrt_id, datum, abfahrtszeit, | INSERT INTO fahrt (fahrt_id, datum, abfahrtszeit, | ||
| - | VALUES (7001,' | + | VALUES (7001,' |
| + | </ | ||
| **Tests A–D** | **Tests A–D** | ||
| - | <WRAP center box 80% round>< | + | <WRAP center box 80% round> |
| + | <code sql> | ||
| -- A) INSERT | -- A) INSERT | ||
| INSERT INTO fahrt (fahrt_id, datum, abfahrtszeit, | INSERT INTO fahrt (fahrt_id, datum, abfahrtszeit, | ||
| - | VALUES (7002,' | + | VALUES (7002,' |
| INSERT INTO fahrt (fahrt_id, datum, abfahrtszeit, | INSERT INTO fahrt (fahrt_id, datum, abfahrtszeit, | ||
| VALUES (7003,' | VALUES (7003,' | ||
| -- B) DELETE Eltern | -- B) DELETE Eltern | ||
| - | DELETE FROM linie WHERE linien_id = 7; | + | DELETE FROM linie WHERE linien_id = 7; -- scheitert (RESTRICT) |
| -- C) UPDATE FK im Kind | -- C) UPDATE FK im Kind | ||
| Zeile 199: | Zeile 212: | ||
| -- D) UPDATE PK in Eltern | -- D) UPDATE PK in Eltern | ||
| - | UPDATE linie SET linien_id = 10 WHERE linien_id = 9; -- scheitert bei referenzierten Zeilen </ | + | UPDATE linie SET linien_id = 10 WHERE linien_id = 9; -- scheitert bei referenzierten Zeilen |
| + | </ | ||
| + | </ | ||
| - | --- | ||
| - | ### Case: Schweizer Regionen (»Kanton« | + | === Case: Schweizer Regionen (Kanton |
| - | **FK: | + | **FK: |
| - | **Mini-Daten** | + | **Daten** |
| - | <WRAP center box 80% round>< | + | <WRAP center box 80% round> |
| + | <code sql> | ||
| INSERT INTO kanton (kanton_id, name, einwohnerzahl, | INSERT INTO kanton (kanton_id, name, einwohnerzahl, | ||
| (2,' | (2,' | ||
| INSERT INTO gemeinde (gemeinde_id, | INSERT INTO gemeinde (gemeinde_id, | ||
| - | VALUES (10001,' | + | VALUES (10001,' |
| + | </ | ||
| + | </ | ||
| **Tests A–D** | **Tests A–D** | ||
| Zeile 218: | Zeile 235: | ||
| -- A) INSERT | -- A) INSERT | ||
| INSERT INTO gemeinde (gemeinde_id, | INSERT INTO gemeinde (gemeinde_id, | ||
| - | VALUES (10002,' | + | VALUES (10002,' |
| INSERT INTO gemeinde (gemeinde_id, | INSERT INTO gemeinde (gemeinde_id, | ||
| - | VALUES (10003,' | + | VALUES (10003,' |
| -- B) DELETE Eltern | -- B) DELETE Eltern | ||
| - | DELETE FROM kanton WHERE kanton_id = 1; | + | DELETE FROM kanton WHERE kanton_id = 1; -- scheitert (RESTRICT), Zürich hängt dran |
| -- C) UPDATE FK im Kind | -- C) UPDATE FK im Kind | ||
| Zeile 229: | Zeile 246: | ||
| -- D) UPDATE PK in Eltern | -- D) UPDATE PK in Eltern | ||
| - | UPDATE kanton SET kanton_id = 3 WHERE kanton_id = 2; -- scheitert bei referenzierten Zeilen </ | + | UPDATE kanton SET kanton_id = 3 WHERE kanton_id = 2; -- scheitert bei referenzierten Zeilen |
| - | + | </ | |
| - | --- | + | </ |
| - | + | ||
| - | <WRAP tip round 80% center> | + | |
| - | **Was ihr hier beobachtet: | + | |
| - | + | ||
| - | * **RESTRICT schützt die Elternzeile**: | + | |
| - | * **INSERT/ | + | |
| - | * **Umhängen** (FK im Kind ändern) ist ok, aber nur auf **existierende** Eltern. | + | |
| - | + | ||
| - | | + | |
| ==== 4) (Optional) SET NULL oder CASCADE bewusst einsetzen ==== | ==== 4) (Optional) SET NULL oder CASCADE bewusst einsetzen ==== | ||
| Zeile 255: | Zeile 262: | ||
| </ | </ | ||
| - | *Einsatzbeispiel: | + | //Einsatzbeispiel: |
| **CASCADE** verwenden wir bevorzugt bei **Zwischentabellen** (N:M). | **CASCADE** verwenden wir bevorzugt bei **Zwischentabellen** (N:M). | ||
| - | Falls euer Case eine N: | + | Falls euer Case eine N: |
| Für reine 1: | Für reine 1: | ||