Relationenschreibweise
Lösung geprüft
Die Aufgabe der heutigen Stunde ist die Relationenschreibweise! Sechs Tabellen einer Schuldatenbank sollen aufgeschrieben und die Schlüssel markiert werden. Das ist die Notation, in der in der Klausur alles dargestellt wird – also lohnt es sich, sie einmal sauber zu üben.
a) Stellen Sie die sechs Tabellen der folgenden Datenbank in der
Relationen-Schreibweise dar. Markieren Sie Primärschlüssel und
Fremdschlüssel.
b) Markieren Sie Primärschlüssel, danach die Fremdschlüssel.
schueler(id, vorname, nachname, strasse, postleitzahl)
orte(postleitzahl, name, bundesland_id)
lehrer(id, vorname, nachname)
schueler_hat_lehrer(schueler, lehrer)
lehrer_hat_faecher(lehrer, fach)
faecher(id, name)
bundeslaender(id, name)
Die Notation
| Zeichen | Bedeutung |
|---|---|
| unterstrichen | Primärschlüssel |
| Pfeil nach oben ↑ (oder FK) | Fremdschlüssel, mit Angabe wohin er zeigt |
| beides↑ | Ist beides gleichzeitig – kommt bei Verknüpfungstabellen vor |
Die Lösung
schueler( id , vorname, nachname, strasse, postleitzahl )
PK FK->orte.postleitzahl
orte( postleitzahl , name, bundesland_id )
PK FK -> bundeslaender.id
lehrer( id , vorname, nachname )
PK
schueler_hat_lehrer( schueler , lehrer )
PK+FK PK+FK
-> schueler.id -> lehrer.id
lehrer_hat_faecher( lehrer , fach )
PK+FK PK+FK
-> lehrer.id -> faecher.id
faecher( id , name )
PK
bundeslaender( id , name )
PK
erDiagram
bundeslaender ||--o{ orte : "bundesland_id"
orte ||--o{ schueler : "postleitzahl"
schueler ||--o{ schueler_hat_lehrer : "schueler"
lehrer ||--o{ schueler_hat_lehrer : "lehrer"
lehrer ||--o{ lehrer_hat_faecher : "lehrer"
faecher ||--o{ lehrer_hat_faecher : "fach"
bundeslaender {
int id PK
string name
}
orte {
int postleitzahl PK
string name
int bundesland_id FK
}
schueler {
int id PK
string vorname
string nachname
string strasse
int postleitzahl FK
}
schueler_hat_lehrer {
int schueler PK, FK
int lehrer PK, FK
}
lehrer {
int id PK
string vorname
string nachname
}
lehrer_hat_faecher {
int lehrer PK, FK
int fach PK, FK
}
faecher {
int id PK
string name
}
Die Tabellen im Einzelnen
| Tabelle | Primärschlüssel | Fremdschlüssel |
|---|---|---|
schueler | id | postleitzahl → orte |
orte | postleitzahl | bundesland_id → bundeslaender |
lehrer | id | keiner |
schueler_hat_lehrer | schueler + lehrer (zusammengesetzt) | beide Attribute |
lehrer_hat_faecher | lehrer + fach (zusammengesetzt) | beide Attribute |
faecher | id | keiner |
bundeslaender | id | keiner |
Die beiden Verknüpfungstabellen
schueler_hat_lehrer und lehrer_hat_faecher
sind die interessanten. Sie haben keine eigene id, und ihre
beiden Attribute sind gleichzeitig Primär- und
Fremdschlüssel.
Der Grund dafür ist eine n:m-Beziehung: ein Schüler hat mehrere Lehrer, und ein Lehrer hat mehrere Schüler. So etwas kann man nicht mit einem einfachen Fremdschlüssel abbilden – in eine einzelne Zelle passt kein halbes Dutzend Lehrer-IDs.
Deshalb legt man eine eigene Tabelle dazwischen. Jede Zeile darin ist
ein einzelnes Paar: „Schüler 7 hat Lehrer 3". Zusammen bilden die beiden
Spalten den Primärschlüssel, weil dasselbe Paar nur einmal vorkommen darf.
Man erkennt solche Tabellen meistens schon am Namen mit dem
_hat_ in der Mitte.
Vorsicht bei den Attributnamen
In schueler_hat_lehrer heißt die Spalte einfach
schueler und nicht schueler_id. Sie ist trotzdem
ein Fremdschlüssel auf schueler.id. Man darf sich beim
Erkennen also nicht nur auf die Endung _id verlassen – es
zählt, worauf das Attribut inhaltlich verweist.
Genauso bei schueler.postleitzahl: da steht kein
_id, und trotzdem ist es ein Fremdschlüssel. Er zeigt auf
orte.postleitzahl, weil die Postleitzahl dort der
Primärschlüssel ist.
Die Kette über drei Ebenen
schueler ---> orte ---> bundeslaender
Über welchen Weg kommt man vom Schüler zu seinem Bundesland? Nicht
direkt – sondern über den Ort. Der Schüler kennt seine Postleitzahl, die
Postleitzahl kennt ihr Bundesland. Solche Ketten löst man später in SQL
mit einem doppelten JOIN auf.