Verbesserungen eines Datenbankschemas
Betrachten wir nochmals die Entität "Pizza". Sie enthält typischerweise an die
10 bis 15 Einträge, die jeweils einen bestimmten Pizzatyp repräsentieren.
Wie ist dann die Relation "fährt" zu verstehen? Fährt ein Angestellter nur
bestimmte Pizzatypen aus? Oder "bäckt" ein Angestellter nur bestimmte Pizzatypen?
Hier steht die Entität "Pizza" sowohl für die Pizzatypen, wie auch die einzelnen
Exemplare. Nehmen wir an, am ersten Abend werden zuerst eine Diavolo, dann
eine Regina, dann noch eine Diavolo und anschließend eine Funghi gebacken:
Es wurden also vier Pizzen gebacken, aber nur drei verschiedene Typen. Die Typen
sind also nur das Pizzarezept, während die Exemplare tatsächlich aus Material
(Pizzateig, Zutaten, Salz, ...) bestehen.
Überprüfung der einzelnen Relationen, die mit "Pizza" etwas zu tun haben ergibt:
- "fährt": ein Angestellter fährt natürlich Exemplare aus
- "bäckt": ein Pizzaservice wird sich normalerweise nicht
den Luxus leisten, einen Bäcker für bestimmte Pizzatypen einzustellen.
Auch hier sind also Exemplare gemeint.
- "enthält": eine Bestellung enthält bestimmte Exemplare, denn man kann
ja mehrere "Pizza Hawai" bestellen.
- "erhält": jeder Kunde erhält Exemplare und keine Typen.
- "enthält": Zutaten(typen) sind Pizzatypen zugeordnet. Sie müssen
also im Rezept erscheinen!
Somit ergibt sich als neues ER-Diagramm:
- Bestellung{Datum, Uhrzeit}
- Angestellter{ID, Name, Adresse, Telefon, Gehalt}
- Kunde{ID, Name, Adresse, Telefon}
- Pizzatyp{Name, Preis}
- Pizzaexemplar{ID}
- Zutaten{Name}
- gibt ab{Bestellung.Uhrzeit,Bestellung.Datum,Kunde.ID}
- nimmt auf{Bestellung.Uhrzeit,Bestellung.Datum,Angestellter.ID}
- bäckt{Angestellter.ID,PizzaExemplar.ID}
- fährt aus{Angestellter.ID,PizzaExemplar.ID}
- erhält{Kunde.ID,PizzaExemplar.ID}
- enthält{Bestellung.Uhrzeit,Bestellung.Datum,PizzaExemplar.ID}
- enthält{Pizzatyp.Name,Zutaten.Name}
- ist vom{PizzaExemplar.ID,Pizzatyp.Name}
Ohne Verlust von Informationen lassen sich nun 1:1- und 1:N-Beziehungen auflösen
und in andere Tabellen integrieren.
Betrachten wir, was mit einem Pizzaexemplar geschieht: Es ist von
einem bestimmten Typ, wird in einer
Bestellung eines Kunden aufgenommen, von evtl mehreren Angestellten
gebacken und von einem Angestellten ausgefahren. Also lassen sich die
1:N-Beziehungen "ist vom", "enthält", "erhält", und "fährt aus" alle in die Relation
Pizzaexemplar integrieren, ohne dass Information verloren geht:
- Bestellung{Datum, Uhrzeit}
- Angestellter{ID, Name, Adresse, Telefon, Gehalt}
- Kunde{ID, Name, Adresse, Telefon}
- Pizzatyp{Name, Preis}
- Pizzaexemplar{ID,
Pizzatyp.Name,Bestellung.Datum,Bestellung.Uhrzeit,
Kunde.ID,Angestellter.ID
}
- Zutaten{Name}
- gibt ab{Bestellung.Uhrzeit,Bestellung.Datum,Kunde.ID}
- nimmt auf{Bestellung.Uhrzeit,Bestellung.Datum,Angestellter.ID}
- bäckt{Angestellter.ID,PizzaExemplar.ID}
- fährt aus{Angestellter.ID,PizzaExemplar.ID}
überflüssig
- erhält{Kunde.ID,PizzaExemplar.ID}
überflüssig
- enthält{Bestellung.Uhrzeit,Bestellung.Datum,PizzaExemplar.ID}
überflüssig
- enthält{Pizzatyp.Name,Zutaten.Name}
- ist vom{PizzaExemplar.ID,Pizzatyp.Name}
überflüssig
Auf die gleiche Weise lassen sich zwei Beziehungen einer Bestellung
durch zusätzliche Angabe von Angestelltem und Kunden beseitigen:
- Bestellung{Datum, Uhrzeit,
Angestellter.ID,Kunde.ID}
- Angestellter{ID, Name, Adresse, Telefon, Gehalt}
- Kunde{ID, Name, Adresse, Telefon}
- Pizzatyp{Name, Preis}
- Pizzaexemplar{ID,Pizzatyp.Name,Bestellung.Datum,Bestellung.Uhrzeit,
Kunde.ID,Angestellter.ID}
- Zutaten{Name}
- gibt ab{Bestellung.Uhrzeit,Bestellung.Datum,Kunde.ID}
überflüssig
- nimmt auf{Bestellung.Uhrzeit,Bestellung.Datum,Angestellter.ID}
überflüssig
- bäckt{Angestellter.ID,PizzaExemplar.ID}
- enthält{Pizzatyp.Name,Zutaten.Name}
Wie man jetzt sieht, ist aber die komplette Relation "Bestellung" in der Relation
"Pizzaexemplar" enthalten (Es gibt keine Bestellung ohne Pizza!).
Ohne Verlust an Information ergibt sich abschließend folgendes Relationensystem:
- Angestellter{ID, Name, Adresse, Telefon, Gehalt}
- Kunde{ID, Name, Adresse, Telefon}
- Pizzatyp{Name, Preis}
- Pizzaexemplar{ID,Pizzatyp.Name,Datum,Uhrzeit,
Kunde.ID,Angestellter.ID}
- Zutaten{Name}
- bäckt{Angestellter.ID,PizzaExemplar.ID}
- enthält{Pizzatyp.Name,Zutaten.Name}