Warum Daten auf Tabellen verteilt sind
Bisher hat jede Abfrage eine einzelne Tabelle gelesen. Die Antwort auf eine alltägliche Frage zum Shop ist aber oft auf mehrere verteilt. Wer hat Bestellung 4 aufgegeben? Die Tabelle bestellungen kennt nur die ID des Kunden. Und was war darin? Das steht in positionen, wieder nur als IDs der Spiele. Warum hält die Datenbank die Dinge so getrennt, obwohl solche Fragen dadurch schwieriger werden?
Stell dir vor, der Shop würde alles in einer großen Tabelle speichern, mit einer Zeile für jede Position jeder Bestellung und allem, was zur Position gehört, direkt in ihrer Zeile. Die Bestellungen von Emma Becker sähen so aus:
| bestellung_id | name | stadt | titel | preis | |
|---|---|---|---|---|---|
| 1 | Emma Becker | emma.becker@mail.de | Hamburg | Cube Logic | 5 |
| 1 | Emma Becker | emma.becker@mail.de | Hamburg | Moon Farm | 20 |
| 4 | Emma Becker | emma.becker@mail.de | Hamburg | Dragon Forge | 40 |
| 14 | Emma Becker | emma.becker@mail.de | Hamburg | Ice Hockey Pro | 45 |
| 14 | Emma Becker | emma.becker@mail.de | Hamburg | Zombie Town | 30 |
| 26 | Emma Becker | emma.becker@mail.de | Hamburg | Knight's Oath | 60 |
Das ist leicht zu lesen, aber dieselben Dinge stehen immer wieder darin. Emmas Name, E-Mail-Adresse und Stadt stehen in jeder Zeile jeder ihrer Bestellungen, und der Titel jedes Spiels stünde in der Zeile jeder Bestellung, in der es vorkommt. Das macht Ärger:
- Jede Änderung muss an vielen Stellen erfolgen. Wenn Emma ihre E-Mail-Adresse ändert, muss sie in allen ihren Zeilen geändert werden. Vergisst man eine, sagt die Tabelle zwei verschiedene Dinge, und niemand weiß, welches stimmt.
- Tippfehler spalten Dinge auf. Steht in einer Zeile „Emma Beker“, sieht sie plötzlich wie zwei verschiedene Kunden aus.
- Manche Dinge haben keinen Platz. Ein Kunde, der noch nichts bestellt hat, oder ein Spiel, das niemand gekauft hat, hätte keine Zeile.
- Die Tabelle ist unnötig groß, weil derselbe Text viele Male gespeichert wird.
Darum teilt eine Datenbank ihre Daten auf Tabellen auf, sodass jedes Ding genau einmal gespeichert ist: Jeder Kunde hat eine Zeile in kunden, jedes Spiel eine Zeile in spiele. Wie du in der ersten Lektion gesehen hast, hat jede dieser Zeilen einen Primärschlüssel, die Spalte id, mit einer Zahl, die keine andere Zeile der Tabelle hat. Andere Tabellen zeigen mit dieser Zahl auf die Zeile, in einem Fremdschlüssel: kunde_id in bestellungen enthält die id eines Kunden, spiel_id in positionen die id eines Spiels. Wenn Emma ihre E-Mail-Adresse ändert, ändert sie sich in einer einzigen Zeile, und alle ihre Bestellungen zeigen weiterhin auf sie.
Der Haken ist, dass die Antwort auf eine Frage jetzt über mehrere Tabellen verteilt ist. Mit dem, was du bisher kennst, musst du den Schlüsseln selbst folgen, eine Abfrage nach der anderen. Zuerst: Wer hat Bestellung 4 aufgegeben?
SELECT kunde_id
FROM bestellungen
WHERE id = 4;| kunde_id |
|---|
| 1 |
Der Kunde mit der ID 1. Du liest die Zahl im Ergebnis ab und benutzt sie in einer zweiten Abfrage:
SELECT name, email
FROM kunden
WHERE id = 1;| name | |
|---|---|
| Emma Becker | emma.becker@mail.de |
Es funktioniert, aber es ist mühsam: Du musstest eine Zahl aus einem Ergebnis in die nächste Abfrage kopieren. Eine Liste aller dreißig Bestellungen mit den Namen ihrer Kunden würde einunddreißig Abfragen erfordern. In der nächsten Übung überlässt du das der Datenbank: Du verbindest die Tabellen in einer einzigen Abfrage.
So schreibst du es:
Anweisungen
- 1
Wer hat Bestellung 13 aufgegeben? Schreibe eine Abfrage, die die
kunde_idund dasbestellt_amder Bestellung zeigt, derenid13 ist:kunde_id bestellt_am 10 2024-12-05 - 2
Füge darunter eine Abfrage hinzu, die den
nameund diestadtdes Kunden mit der ID zeigt, die du gefunden hast:name stadt Oskar Klein Berlin - 3
Und was hat er gekauft? Die Zeilen von
positionen, derenbestellung_id13 ist, enthalten die IDs der Spiele. Finde sie im Tab „Tabellen“ oder mit einer eigenen Abfrage. Füge dann eine Abfrage hinzu, die dieidund dentiteldieser Spiele zeigt, sortiert nachid. MitINund einer Liste der IDs reicht eine einzige Abfrage:id titel 3 Moon Farm 16 Bakery Story