Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Nächste Überarbeitung
Vorhergehende Überarbeitung
modul:m290_guko:learningunits:lu08:theorie:e_many-to-many [2025/10/19 22:55] – angelegt gkochmodul:m290_guko:learningunits:lu08:theorie:e_many-to-many [2025/10/26 18:18] (aktuell) gkoch
Zeile 6: Zeile 6:
 (Die Verknüpfung **users ↔ posts** ist 1:N; **posts ↔ categories** ist N:M.) (Die Verknüpfung **users ↔ posts** ist 1:N; **posts ↔ categories** ist N:M.)
  
-==== Warum N:M auflösen? (kurz) ==== +==== Warum N:M auflösen? ==== 
-In einer relationalen Tabelle zeigt ein Fremdschlüssel **immer nur auf genau eine** Zeile.+In einer relationalen Tabelle kann ein Fremdschlüssel **immer nur auf genau eine** Zielzeile verweisen.
 Bei **N:M** gilt jedoch: **ein Post → mehrere Kategorien** und **eine Kategorie → mehrere Posts**. Bei **N:M** gilt jedoch: **ein Post → mehrere Kategorien** und **eine Kategorie → mehrere Posts**.
-Das lässt sich **nicht** mit einem einzigen FK-Feld abbilden: 
  
-  - FK in ''posts'' nur als ''category_id'': Pro Post wäre nur eine Kategorie möglich. Mehrere Kategorien erzwingen Duplikate desselben Posts – Änderungen und Löschungen werden fehleranfällig. 
-  - FK in ''categories'' nur als ''post_id'': Pro Kategorie wäre nur ein Post möglich. Dadurch müsste man Kategorien duplizieren – gleiches Problem wie bei obigen Punkt. 
-  - Kommaliste in einer Spalte (z. B. ''Belgien, Städtereise''): In einer Zelle stehen mehrere Werte. Die Datenbank kann nicht prüfen, ob diese Kategorien existieren (kein FK), Abfragen werden unzuverlässig und langsam. 
-  - mehrere FK-Spalten (z.B. category_id1, category_id2 etc.) pro Post oder Kategorie: Das limitiert die Anzahl mögliche Kategorien, die einem Post zugewiesen können (limitiert die Anzahl an Beziehungen, da bei der Tabellendefinition die Spalten definiert werden müssen. 
  
-Gleich hier ein paar Tabellen, die die einzelnen vorhin aufgeführten Punkte visualisieren **alles sind schlechte Lösungen** (s. obige Punkte):+Das lässt sich mit **einem** FK-Feld nicht sauber abbilden:
  
-{{:modul:m290_guko:learningunits:lu08:theorie:many-to-many_not-resolved.png?direct&800|}} +  * FK in ''posts'' nur als ''category_id''Pro Post wäre **nur eine** Kategorie möglich. Mehrfachzuordnungen erzwingen **Duplikate desselben Posts** → Änderungen/Löschungen an mehreren Stellen, fehleranfällig. 
 +  * FK in ''categories'' nur als ''post_id''Pro Kategorie wäre **nur ein** Post möglich. Für mehrere Posts müsste man Kategorien **duplizieren** → Eindeutigkeit geht verloren. 
 +  * Kommaliste in einer Spalte (z. B. ''Belgien, Städtereise'')In **einer Zelle stehen mehrere Werte**. Die DB kann nicht prüfen, ob diese Kategorien existieren (kein FK); Abfragen werden **unzuverlässig** und **langsam**. 
 +  * Mehrere FK-Spalten (z. B. ''category_id1'', ''category_id2'' …): Die Anzahl möglicher Zuordnungen ist **künstlich begrenzt**; das Schema müsste bei neuen Fällen **ständig erweitert** werden.
  
 +Die folgenden Tabellen-Skizzen visualisieren diese Ansätze – **alles sind schlechte Lösungen** (siehe oben):
 +
 +{{:modul:m290_guko:learningunits:lu08:theorie:many-to-many_not-resolved.png?direct&800|}}
  
 **Lösung: die Zwischentabelle ''post_category''.** **Lösung: die Zwischentabelle ''post_category''.**
 Wir trennen die Objekte (''posts'', ''categories'') und speichern **jede einzelne Zuordnung** als eigene Zeile in ''post_category'' – genau **ein Paar** (''post_id'', ''category_id'') pro Zeile. Wir trennen die Objekte (''posts'', ''categories'') und speichern **jede einzelne Zuordnung** als eigene Zeile in ''post_category'' – genau **ein Paar** (''post_id'', ''category_id'') pro Zeile.
-So bleibt jede Beziehung eindeutig modelliert, Primärschlüssel bleiben eindeutig, Fremdschlüssel sind prüfbar, und Abfragen bleiben klar und performant.+So bleibt jede Beziehung **eindeutig** modelliert, Primärschlüssel bleiben eindeutig, Fremdschlüssel sind **prüfbar**, und Abfragen bleiben **klar** und **performant**. 
  
-=== Visualisierung (Kontext) === +=== N:M mit Zwischentabelle ===
-**users ↔ posts (1:N)** +
-{{:modul:m290_guko:learningunits:lu08:theorie:reiseblog-connected_users-posts.png?direct&1600|}}+
  
 **posts ↔ categories (N:M) – korrekt über Zwischentabelle ''post_category''** **posts ↔ categories (N:M) – korrekt über Zwischentabelle ''post_category''**
Zeile 40: Zeile 40:
  
 CREATE TABLE post_category ( CREATE TABLE post_category (
-post_id     INT NOT NULL, +  post_id     INT NOT NULL, 
-category_id INT NOT NULL, +  category_id INT NOT NULL, 
-PRIMARY KEY (post_id, category_id), +  PRIMARY KEY (post_id, category_id), 
-FOREIGN KEY (post_id) REFERENCES posts (post_id) ON DELETE CASCADE ON UPDATE CASCADE, +  FOREIGN KEY (post_id) REFERENCES posts (post_id) ON DELETE CASCADE ON UPDATE CASCADE, 
-FOREIGN KEY (category_id) REFERENCES categories (category_id) ON DELETE CASCADE ON UPDATE CASCADE+  FOREIGN KEY (category_id) REFERENCES categories (category_id) ON DELETE CASCADE ON UPDATE CASCADE
 ); );
 </code> </code>
Zeile 92: Zeile 92:
  
 **Erwartung:** Die letzte Abfrage liefert **keine Zeilen** (CASCADE hat die Zuordnungen bereinigt). **Erwartung:** Die letzte Abfrage liefert **keine Zeilen** (CASCADE hat die Zuordnungen bereinigt).
- 
-===== 4) Aufgaben ===== 
- 
-  * **Aufgabe A:** Fügen Sie eine neue Kategorie `Benelux` (slug: benelux) ein und ordnen Sie //Hasselt – 10 Highlights// zusätzlich dieser Kategorie zu. Prüfen Sie danach, ob drei Kategorien für den Post angezeigt werden. 
-  * **Aufgabe B:** Löschen Sie die Kategorie //roadtrip//. Prüfen Sie, dass die Posts weiterhin existieren und nur die entsprechenden //post_category//-Zeilen verschwunden sind (CASCADE). 
  
 ===== Zusammenfassung ===== ===== Zusammenfassung =====
  
-* **N:M** wird **immer** über eine **Zwischentabelle** mit **einer Paarung pro Zeile** modelliert: //(post_id, category_id)//+  * **N:M** wird **immer** über eine **Zwischentabelle** mit **einer Paarung pro Zeile** modelliert: //(post_id, category_id)//
-* **Fremdschlüssel** sichern die Datenqualität; mit **ON DELETE CASCADE** werden Zuordnungen automatisch aufgeräumt.+  * **Fremdschlüssel** sichern die Datenqualität; mit **ON DELETE CASCADE** werden Zuordnungen automatisch aufgeräumt. 
 + 
 +==== Weiterführende Videos ==== 
 +<WRAP center tip round 80%> 
 +[[https://www.youtube.com/watch?v=4q-keGvUnag|One-to-many and many-to-many table relationships]]((LinkedIn Learning / YouTube)) -> (9:50, en, nutzen Sie auto-subs) Praxisnahes Vorgehen für N:M mit einer Zwischentabelle; gute Vertiefung zur Tabelle ''post_category''
 +</WRAP>
  
 <WRAP tip round 80% center> <WRAP tip round 80% center>
 **Ausblick auf LU09:** Wir formulieren dieselben Abfragen für mehrere Tabellen </WRAP> **Ausblick auf LU09:** Wir formulieren dieselben Abfragen für mehrere Tabellen </WRAP>
  
  • modul/m290_guko/learningunits/lu08/theorie/e_many-to-many.1760907314.txt.gz
  • Zuletzt geändert: 2025/10/19 22:55
  • von gkoch