====== Lösung: Postzustellung und Post-Briefkästen ====== {{:de:modul:m290_guko:learningunits:lu06:loesungen:postgebiete_crowsfoot.drawio.png?direct&1200|Crow's-Foot-Diagramm Postgebiete}} //Klicken Sie aufs Bild, um es vergrössert anzuzeigen.// ===== Fremdschlüssel ===== * **gebiet_id** steht in **briefkasten**. Ein Postgebiet enthält viele Briefkästen, ein Briefkasten gehört zu genau einem Gebiet (1:n). * **poestler_id** steht in **postgebiet** (1:1-Beziehung). Ein Postgebiet kann bereits existieren, bevor ihm eine Person zugeteilt ist – dieselbe Logik wie beim Team ohne Trainer. **1:1 in SQL wirklich erzwingen:** Der Fremdschlüssel allein reicht nicht aus – ohne zusätzliche Regel könnte dieselbe Person zwei Postgebieten zugewiesen werden. Dafür bräuchte **poestler_id** in der Tabelle postgebiet zusätzlich den Constraint **UNIQUE**. **Im Prinzip wäre hier eine Korrektur nötig:** Der **plz_bereich CHAR(9)** speichert eine Spanne wie "6000-6100" in einer einzigen Zelle. Das verletzt die Regel "eine Zelle, ein Wert": Man kann so weder prüfen, ob eine bestimmte PLZ zu einem Gebiet gehört, noch sinnvoll sortieren. Bessere Alternative: **plz_von CHAR(4)** und **plz_bis CHAR(4)** als zwei Spalten ===== Datentypen ===== ^ Spalte ^ Typ ^ Begründung ^ | briefkasten_id, gebiet_id, poestler_id | INT | Ganzzahlige IDs | | standort | VARCHAR(100) | Textbeschreibung wie "bei der Bushaltestelle" | | leerungszeit | TIME | Nur die Uhrzeit ist relevant, kein Datum (weil üblicherweise an mehreren Wochentagen zur gleichen Zeit geleert wird) | | name | VARCHAR | Textlänge variabel | ===== SQL: Tabellen erstellen ===== Fremdschlüssel-Spalten sind angelegt, aber noch **ohne FOREIGN-KEY-Constraint** – den setzen wir später im Modul. CREATE TABLE poestler_in ( poestler_id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50) NOT NULL ); CREATE TABLE postgebiet ( gebiet_id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(20) NOT NULL, plz_bereich CHAR(9), poestler_id INT UNIQUE ); CREATE TABLE briefkasten ( briefkasten_id INT AUTO_INCREMENT PRIMARY KEY, standort VARCHAR(100), leerungszeit TIME, gebiet_id INT );