# Aufgabe 1 > Dauer: 2 h ## 1) ![ERD](ERD M4-1-1.png) ## 2) Datenbankentwurf in Relationenschreibweise ```sql use emensawerbeseite; -- Tabelle 'Ersteller' erstellen CREATE TABLE IF NOT EXISTS Ersteller ( EMail VARCHAR(255) PRIMARY KEY, Name VARCHAR(255) DEFAULT 'anonym' ); -- Tabelle 'Wunschgericht' erstellen CREATE TABLE IF NOT EXISTS Wunschgericht ( ID INT AUTO_INCREMENT PRIMARY KEY, Name VARCHAR(255) NOT NULL, Beschreibung TEXT, Erstellungsdatum DATE NOT NULL, Ersteller_EMail VARCHAR(255) NOT NULL, FOREIGN KEY (Ersteller_EMail) REFERENCES Ersteller(EMail) ); ``` ## 6) ### a) ````sql select * from wunschgericht order by Erstellungsdatum desc limit 5; ```` ### b) ````sql -- basierend auf M3 6) 4) select ersteller.Name, count(Ersteller_EMail) as anzahl from wunschgericht, ersteller where ersteller.EMail = wunschgericht.Ersteller_EMail group by Ersteller_EMail order by anzahl desc ; ```` --- # Aufgabe 2 > Dauer: 2h Bei der Übergabe von Daten in die DB müssen diese geprüft werden. Bei der Ausgabe von Daten aus der DB im HTML Code müssen diese Maskiert werden. ````php // wunschgericht.php // Zeile 33 $sql_ersteller_exists = "SELECT * FROM ersteller WHERE EMail = '" . $ersteller_email . "'"; $sql_ersteller_exists = "SELECT * FROM ersteller WHERE EMail = '" . mysqli_real_escape_string($link, $ersteller_email) . "'"; // Zeile 36 $sql_ersteller = "INSERT INTO ersteller(EMail, Name) VALUES ('" . $ersteller_email . "','" . $ersteller_name . "')"; $sql_ersteller = "INSERT INTO ersteller(EMail, Name) VALUES ('" . mysqli_real_escape_string($link, $ersteller_email) . "','" . mysqli_real_escape_string($link, $ersteller_name) . "')"; // Zeile 42 $sql = "INSERT INTO wunschgericht(Name, Beschreibung, Erstellungsdatum, Ersteller_EMail) VALUES ('" . $gericht_name . "','" . $gericht_beschreibung . "','". $date ."','" . $ersteller_email . "')"; $sql = "INSERT INTO wunschgericht(Name, Beschreibung, Erstellungsdatum, Ersteller_EMail) VALUES ('" . mysqli_real_escape_string($link, $gericht_name) . "','" . mysqli_real_escape_string($link, $gericht_beschreibung) . "','".$date."','" . mysqli_real_escape_string($link, $ersteller_email) . "')"; ?> ```` ````php // index.php // Zeile 43 $sql_besucher = "UPDATE besucher_counter SET besucher =".$besucherCount; $sql_besucher = "UPDATE besucher_counter SET besucher =". mysqli_real_escape_string($link, $besucherCount); // Zeile 190 $tabelle .= "" . $row_gerichte['name'] . " " . $allergene . "" . $preisintern . "€" . $preisextern . "€Kein Bild in der Datenbank "; $tabelle .= "" . htmlspecialchars($row_gerichte['name']) . " " . htmlspecialchars($allergene) . "" . htmlspecialchars($preisintern) . "€" . htmlspecialchars($preisextern) . "€Kein Bild in der Datenbank "; // Zeile 202 $verwendete_allergene_string .= "".$row_allergen['code']." ". $row_allergen['name']. ", "; $verwendete_allergene_string .= "". htmlspecialchars($row_allergen['code']) ." ". htmlspecialchars($row_allergen['name']) . ", "; // Zeile 214f echo $besucherCount; echo $newletterCount; echo htmlspecialchars($besucherCount); echo htmlspecialchars($newletterCount); // Zeile 220 echo $ausgabe["COUNT(id)"]; echo htmlspecialchars($ausgabe["COUNT(id)"]); ```` Bei der Newsletteranmeldung sollte man sich auch ggf. überlegen, wie man die Eingaben prüft un zu vermeiden, das schadhafter Code gespeichert und später abgerufen wird. # Aufgabe 4 > Dauer 1,5 h 1. Eindeutigkeit für die Kombination aus Gericht und Kategorie sicherstellen ````sql ALTER TABLE gericht_hat_kategorie ADD CONSTRAINT gericht_kategorie_unique UNIQUE (gericht_id, kategorie_id); ```` 2. In der Tabelle gericht soll eine Abfrage nach Name beschleunigt werden. ````sql ALTER TABLE gericht ADD INDEX idx_name (name); ```` 3. Bei Löschung eines Gerichts sollen 1) die zugehörigen Zuordnungen zu einer Kategorie sowie ````sql ALTER TABLE gericht_hat_kategorie DROP FOREIGN KEY gericht_hat_kategorie_ibfk_1, -- (gericht_id) -> gericht(id) ADD CONSTRAINT gericht_hat_kategorie_ibfk_1_new FOREIGN KEY (gericht_id) REFERENCES gericht(id) ON DELETE CASCADE; ```` 2) die zugehörigen Zuordnungen zu Allergenen automatisch mit gelöscht werden. ````sql ALTER TABLE gericht_hat_allergen DROP FOREIGN KEY gericht_hat_allergen_ibfk_2, -- (gericht_id) -> gericht(id) ADD CONSTRAINT gericht_hat_allergen_ibfk_2_new FOREIGN KEY (gericht_id) REFERENCES gericht(id) ON DELETE CASCADE; ```` 4. Eine Kategorie kann nur dann gelöscht werden, wenn 1) dieser keine Gerichte zugeordnet sind und ````sql ALTER TABLE gericht_hat_kategorie ADD CONSTRAINT fk_gericht_hat_kategorie_kategorie_id FOREIGN KEY (kategorie_id) REFERENCES kategorie(id) ON DELETE RESTRICT; ```` 2) diese keine Kindkategorien besitzt. ````sql ALTER TABLE kategorie ADD CONSTRAINT fk_kategorie_eltern_id FOREIGN KEY (eltern_id) REFERENCES kategorie(id) ON DELETE RESTRICT; ```` 5. Wird der Code eines Allergens verändert, so ändert sich dieser Code automatisch in den referenzierenden Datensätzen. ````sql ALTER TABLE gericht_hat_allergen DROP FOREIGN KEY gericht_hat_allergen_ibfk_1, -- (code) -> allergen(code) ADD CONSTRAINT gericht_hat_allergen_ibfk_1_new FOREIGN KEY (code) REFERENCES allergen(code) ON UPDATE CASCADE; ```` 6. Eine Kombination aus ``gericht_id`` und ``kategorie_id`` in ``gericht_hat_kategorie`` soll als Primärschlüssel dienen. ````sql ALTER TABLE gericht_hat_kategorie ADD PRIMARY KEY (gericht_id, kategorie_id); ```` # Aufgabe 6 > Dauer 20 min # Aufgabe 7 > Dauer 2,5 h # Aufgabe 8 > Dauer 1 h