Die Miniwelt ist ein Ausschnitt der realen Welt. Beispiel: Personen haben eine Personalnummer und einen Namen. Dadurch reduzieren wir Personen auf lediglich diese beiden Eigenschaften, die in unserer Miniwelt relevant sind. Das konzeptionelle Schema kann manuell oder semi-automatisch in ein Datenbankschema transformiert werden, z. B. in CREATE TABLE
-Befehle oder ein XML-Schema.
Ziele des DB-Entwurfs
Genaue Abbildung
Aktuell
Verständlich
Simpel
Redundanzfrei
[[
{ _e: "Personen", pos: [150, 100],
attributes: [
{ _a:"Vorname", options:["primary"], pos: [89, 13] },
{ _a:"MySpace-URL", pos: [245, 13] },
{ _a:"ZKX-Nr.", pos: [175, 183]}
]
}
],
[
]]
Viele Fehler und Probleme fallen bereits in der Modellierungsphase auf. So können sie frühzeitig behandelt werden.
Im schlechten Beispiel-Diagramm auf dieser Folie fehlen wichtige Attribute, z. B. der Nachname. Außerdem ist ein Vorname kein sinnvoller Primärschlüssel. Die MySpace-URL ist vermutlich veraltet und was die KNX-Nr. ist, ist unklar. Wird frühzeitig gemäß Kundenanforderungen ein solches konzeptionelles Modell angefertigt, kann Kundenfeedback erfragt und eingearbeitet werden und somit das Modell schrittweise den Anforderungen des Kunden gerecht werden.
Entity-Relationship-Modell
Das ERM modelliert Dinge (Entities) und Beziehungen (Relationships) zwischen diesen.
7
[[
{ _e: "Entitätstyp 1", pos: [150, 100] },
{ _e: "Entitätstyp 2", pos: [530, 100] }
],
[
{ _r: "Beziehung",
_e: ["Entitätstyp 1", "Entitätstyp 2"],
card: ["", ""]
}
]]
Im ER-Diagramm werden Entitätstypen als Rechtecke dargestellt. Ein Entitätstyp ist so etwas wie eine Klasse. Instanzen eines Entitätstypen werden Entities genannt. Das ER-Modell beschreibt also, wie mögliche Entities aussehen können und wie sie in Beziehung zueinander stehen können.
Entitätstypen und Entities
[[
{ _e: "Personen", pos: [20, 50] }
],
[
]]
Entitätstyp
Rechteck im ER-Diagramm
z. B. "Personen"
Entität
Unterscheidbare Objekte der Miniwelt
Ausprägungen von Entitätstypen
z. B. "Peter mit der Personalnummer 5"
Entitäten tauchen nicht im ER-Diagramm auf
ER-Diagramme stellen Metadaten dar. Sie beschreiben, was in einer Datenbank gespeichert werden kann. Sie beinhalten nicht die Daten selbst.
Was ist ein sinnvoller Entitätstyp?
Webshop
Kunden
Login
Titanik
https://frage.space
Attribute
Eigenschaften von Entitäten und Entitätstypen
Haben Werte
Ellipsen im ER-Diagramm
"Peter hat die Personalnummer 5"
"Personen haben eine Personalnummer und einen Namen"
[[
{ _e: "Personen", pos: [130, 100],
attributes: [
{ _a:"PersNr", options:["primary"], pos: [69, 13] },
{ _a:"Name", pos: [225, 13] }
]
}
],
[
]]
Bei der Erstellung von ER-Diagrammen hilft es immer, sich konkrete Ausprägungen der Entitätstypen vorzustellen, z. B. hier Peter mit der Personalnummer 5, auch wenn Peter nichts im ER-Diagramm zu suchen hat. Wenn man sich jedoch keine Ausprägungen vorstellen kann, hat man meist einen Fehler beim Erstellen des Entitätstyp gemacht. "Personalabteilung" oder "Datenbank" sind zum Beispiel keine sinnvollen instanziierbaren Entitätstypen. Attribute haben einen Datentypen, welcher jedoch im ER-Diagramm in der Regel nicht spezifiziert wird. Auch andere Eigenschaften, z. B. ob ein Attribut Pflicht oder optional ist, tauchen meist im ER-Diagramm nicht auf.
Primärschlüssel
8
Entitäten müssen wohlunterscheidbar sein
1 oder mehr Attribute bilden den Primärschlüssel
Beschreibt eine Entität eindeutig
Im ER-Diagramm: Attribut(e) unterstreichen
[[
{ _e: "Personen", pos: [150, 100],
attributes: [
{ _a:"PersNr", options:["primary"], pos: [89, 13] },
{ _a:"Name", pos: [245, 13] }
]
},
{ _e: "Termine", pos: [530, 100],
attributes: [
{ _a:"Datum", pos: [415, 15], options:["primary"] },
{ _a:"Uhrzeit", pos: [535, 15], options:["primary"] },
{ _a:"Raum", pos: [655, 15], options:["primary"] },
{ _a:"Dauer", pos: [765, 40]},
{ _a:"Bezeichnung", pos: [765, 110]}
]
}
],
[
]]
Darf es am gleichen Tag zur gleichen Uhrzeit mehr als ein Termin geben?
Ja, sogar im gleichen Raum
Nein, auf keinen Fall
Ja, aber nicht im gleichen Raum
Nein, allein das Datum muss schon eindeutig sein
https://frage.space
Der Personen-Entitätstyp hat als Primärschlüsselattribut die Personennummer. Dies kann zum Beispiel eine künstlich erzeugte laufende Nummer sein. Termine haben keine solche ID. Hier haben wir einen zusammengesetzten Primärschlüssel aus Datum, Uhrzeit und Raum. Dies bedeutet, dass es am gleichen Tag zur gleichen Zeit im gleichen Raum nur einen einzigen Termin geben darf. Manchmal gibt es mehrere Möglichkeiten, was der Primärschlüssel sein kann (sogenannte Schlüsselkandidaten ). Dann muss man sich für einen entscheiden.
Unterattribute
Attribute können aus mehreren Sub-Attributen zusammengesetzt sein.
[[
{ _e: "Personen", pos: [150, 100],
attributes: [
{ _a:"PersNr", options:["primary"], pos: [89, 13] },
{ _a:"Name", pos: [245, 13] },
{ _a:"Adresse", pos: [409, 105],
attributes: [
{ _a: "Straße", pos: [324, 160] },
{ _a: "PLZ", pos: [437, 188] },
{ _a: "Ort", pos: [550, 170] }
] }
]
}
],
[
]]
Personen haben eine Adresse, die aus Straße, Postleitzahl und Ort besteht. Unterattribute können natürlich auch wieder mit Unterattributen versehen werden, um sie noch weiter hierarchisch zu strukturieren.
Mehrwertige Attribute
[[
{ _e: "Personen", pos: [150, 100],
attributes: [
{ _a:"PersNr", options:["primary"], pos: [89, 13] },
{ _a:"Name", pos: [245, 13] },
{ _a:"Telefon", pos: [409, 105], options:["multi"] }
]
}
],
[
]]
[[
{ _e: "Personen", pos: [150, 100],
attributes: [
{ _a:"PersNr", options:["primary"], pos: [89, 13] },
{ _a:"Name", pos: [245, 13] },
{ _a:"Telefon", pos: [409, 105], options:["multi"],
attributes: [
{ _a:"Typ", pos: [527, 62] },
{ _a:"Nummer", pos: [527, 130] }
] }
]
}
],
[
]]
Eine Person hat eine Personennummer, einen Namen, aber mehrere (beliebig viele) Telefonnummern. Im unteren Beispiel hat eine Person mehrere Telefonnummern, die wiederrum aus Typ (z. B. "mobil") und der Telefonnummer bestehen. Es sind beliebige Schachtelungen möglich.
Beziehungen
9-10, 12
Beteiligt sind mind. 2 Entity-Typen
Rauten im ER-Diagramm
Funktionalitäten: 1:1, 1:N / N:1, N:M
[[
{ _e: "Personen", pos: [150, 100],
attributes: [
{ _a:"PersNr", options:["primary"], pos: [89, 13] },
{ _a:"Name", pos: [245, 13] }
]
},
{ _e: "Termine", pos: [530, 100],
attributes: [
{ _a:"Datum", pos: [475, 25], options:["primary"] },
{ _a:"Uhrzeit", pos: [634, 25], options:["primary"] },
{ _a:"Raum", pos: [722, 106], options:["primary"] },
{ _a:"Dauer", pos: [650, 189]},
{ _a:"Bezeichnung", pos: [475, 189]}
]
}
],
[
{ _r: "haben",
_e: ["Personen", "Termine"],
card: ["1", "N"]
}
]]
1:N-Beziehungen
Eine Person hat N Termine (beliebig viele)
Ein Termin gehört immer zu einer Person
Man muss den Satz immer mit "Ein(e)..." beginnen. Je nachdem, ob man den Satz fortfährt mit "... hat 1" oder "... hat N", kommt dementsprechend eine 1 oder ein N an den gegenüberliegenden Entitätstypen.
1:N-Beziehungen
Eine Person hat N Termine (beliebig viele)
Peter hat einen Friseurtermin
Peter hat einen Zahnarzttermin
Peter hat Fußballtraining
Ein Termin gehört immer zu einer Person
Der Friseurtermin befindet sich in Peters Kalender
Der Primärschlüssel von Person ist die PersNr. Wenn wir sagen, dass Peter PersNr 5 hat, kann diese Person beliebig viele Termine haben (0, 1, 2, etc.). Primärschlüssel vom Termin ist (Datum, Uhrzeit, Raum). Da wir die Beziehung "Personen haben Termine" als 1:N definiert haben, darf es für einen bestimmten Termin (z. B. Montag 14:45 Uhr, Raum D14/404) nur eine einzige Person (oder keine!) geben, die diesen Termin hat.
N:M-Beziehungen
[[
{ _e: "Personen", pos: [150, 100],
attributes: [
{ _a:"PersNr", options:["primary"], pos: [89, 13] },
{ _a:"Name", pos: [245, 13] }
]
},
{ _e: "Termine", pos: [530, 100],
attributes: [
{ _a:"Datum", pos: [475, 25], options:["primary"] },
{ _a:"Uhrzeit", pos: [634, 25], options:["primary"] },
{ _a:"Raum", pos: [722, 106], options:["primary"] },
{ _a:"Dauer", pos: [650, 189]},
{ _a:"Bezeichnung", pos: [475, 189]}
]
}
],
[
{ _r: "nehmen teil",
_e: ["Personen", "Termine"],
card: ["N", "M"]
}
]]
Eine Person nimmt an beliebig vielen Terminen teil
An einem Termin können beliebig viele Person teilnehmen
Auch hier lesen wir wieder "Eine Person..." und "An einem Termin...". Da in beiden Sätze im zweiten Teil "beliebig viele" steht, schreiben wir an die Linien ein N und ein M. Man schreibt nicht N:N, sondern N:M, da es sich in der Regel um unterschiedliche Zahlen handelt. Nur weil Peter 5 Termine hat, heißt das nicht, dass an jedem seiner Termine 5 Personen teilnehmen.
N:M-Beziehungen
Eine Person hat beliebig viele Termine
Peter hat einen Friseurtermin
Peter hat Fußballtraining
An einem Termin können beliebig viele Person teilnehmen
Am Friseurtermin nimmt Peter teil
Am Fußballtraining nimmt Peter teil
Am Fußballtraining nimmt Katja teil
1:1-Beziehung
11
[[
{ _e: "Personen", pos: [150, 100],
attributes: [
{ _a:"PersNr", options:["primary"], pos: [89, 13] },
{ _a:"Name", pos: [245, 13] }
]
},
{ _e: "Kreditkarten", pos: [530, 100],
attributes: [
{ _a:"Kreditkartennr", pos: [475, 25], options:["primary"] },
{ _a:"Ablaufdatum", pos: [595, 25] },
{ _a:"Typ", pos: [702, 63] },
{ _a:"Sicherheitscode", pos: [702, 135]}
]
}
],
[
{ _r: "haben",
_e: ["Personen", "Kreditkarten"],
card: ["1", "1"]
}
]]
Eine Person hat 1 Kreditkarte
Eine Kreditkarte gehört immer nur zu einer Person
[[
{ _e: "Personen", pos: [400, 100],
attributes: [
{ _a:"PersNr", options:["primary"], pos: [235, 78] },
{ _a:"Name", pos: [310, 20] },
{ _a:"Kreditkartennr", pos: [430, 6] },
{ _a:"Ablaufdatum", pos: [550, 6] },
{ _a:"Typ", pos: [626, 48] },
{ _a:"Sicherheitscode", pos: [637, 109]}
]
}
],
[]]
Statt einer 1:1-Beziehung kann man sich auch oft die Beziehung sparen und alles in einem Entitätstypen modellieren.
Rekursive Beziehung
"Beziehung mit sich selbst"
Entitätstyp nimmt mehrfach an einer Beziehung teil
Rollennamen zur Unterscheidung notwendig
Hier wurden die Rollennamen "Mitarbeiter" und "Chef" an die Linien geschrieben. Eine Person hat nur einen Chef, aber sie kann mehrere Mitarbeiter unter sich haben, d.h. sie kann Chef von mehreren Personen sein.
Beziehungsattribute
11
[[
{ _e: "Personen", pos: [150, 100],
attributes: [
{ _a:"PersNr", options:["primary"], pos: [89, 13] },
{ _a:"Name", pos: [245, 13] }
]
},
{ _e: "Termine", pos: [530, 100],
attributes: [
{ _a:"Datum", pos: [475, 25], options:["primary"] },
{ _a:"Uhrzeit", pos: [634, 25], options:["primary"] },
{ _a:"Raum", pos: [722, 106], options:["primary"] },
{ _a:"Dauer", pos: [650, 189]},
{ _a:"Bezeichnung", pos: [475, 189]}
]
}
],
[
{ _r: "nehmen teil",
_e: ["Personen", "Termine"],
card: ["N", "M"],
attributes: [ {_a:"ist Organisator", pos: [317, 194] } ]
}
]]
Peter nimmt am Fußballtraining teil und ist Organisator
Katja nimmt am Fußballtraining teil und ist kein Organisator
Webshop-Beispiel
11
[[
{ _e: "Kunden", pos: [150, 100],
attributes: [
{ _a:"Kundennr", options:["primary"], pos: [40, 15] },
{ _a:"Name", pos: [159, 9] },
{ _a:"E-Mail", pos: [280, 25] }
]
},
{ _e: "Produkte", pos: [630, 100],
attributes: [
{ _a:"Produktnr", pos: [575, 25], options:["primary"] },
{ _a:"Bezeichnung", pos: [734, 25] },
{ _a:"Preis", pos: [822, 106] }
]
},
{ _e: "Hersteller", pos: [577, 304],
attributes: [
{ _a:"Firma", pos: [750, 280], options:["primary"] },
{ _a:"Land", pos: [750, 345] }
]
}
],
[
{ _r: "sind von", pos: [612, 191],
_e: ["Produkte", "Hersteller"],
card: ["N", "1"] },
{ _r: "bewerten",
_e: ["Kunden", "Produkte"],
card: ["N", "M"],
attributes: [ {_a:"Sterne", pos: [317, 194] }, {_a:"Text", pos: [430, 194] } ]
}
]]
Kunden bewerten Produkte mit Sternen und einem Bewertungstext. Die Beziehungsattribute Sterne und Text werden direkt an die Beziehung geschrieben. Nicht Kunden haben Sterne, auch Produkte haben keine Sterne, sondern die Bewertung: Peter bewertet die Spülmaschinentabs mit einem Stern und schreibt: 'Mein Geschirr wird nicht sauber.'
N:M-Bez. vs. eigener Entitätstyp
[[
{ _e: "Kunden", pos: [50, 10],
attributes: [
{ _a:"Kundennr", options:["primary"], pos: [10, 85] },
{ _a:"...", pos: [140, 85] }
]
},
{ _e: "Produkte", pos: [730, 10],
attributes: [
{ _a:"Produktnr", options:["primary"], pos: [690, 85] },
{ _a:"...", pos: [810, 85] }
]
}
],
[
{ _r: "bewerten",
_e: ["Kunden", "Produkte"],
card: ["N", "M"],
attributes: [ {_a:"Sterne", pos: [340, 100] }, {_a:"Text", pos: [480, 100] } ]
}
]]
[[
{ _e: "Kunden", pos: [50, 10],
attributes: [
{ _a:"Kundennr", options:["primary"], pos: [10, 85] },
{ _a:"...", pos: [140, 85] }
]
},
{ _e: "Produkte", pos: [730, 10],
attributes: [
{ _a:"Produktnr", options:["primary"], pos: [690, 85] },
{ _a:"...", pos: [810, 85] }
]
},
{ _e: "Bewertungen", pos: [390, 10],
attributes: [
{_a:"Bewertungsnr", pos: [300, 100], options:["primary"]},
{_a:"Sterne", pos: [430, 100] },
{_a:"Text", pos: [560, 100] } ]
}
],
[
{ _r: "schreiben",
_e: ["Kunden", "Bewertungen"],
card: ["1", "N"]
},
{ _r: "für",
_e: ["Bewertungen", "Produkte"],
card: ["N", "1"]
}
]]
Die beiden hier dargestellten Lösungen ist fast äquivalent. Da Entitätstypen stets einen Primärschlüssel benötigen, muss es im unteren Beispiel, in dem Bewertungen als Entitätstyp modelliert wird, eine Bewertungsnummer oder ähnliches geben. Mit schwachen Entitätstypen (siehe nächste Folie) lässt sich dies jedoch auch ohne Primärschlüssel lösen (siehe übernächste Folie).
Schwache Entitätstypen
13
Kein eigener Primärschlüssel, stattdessen wird der Primärschlüssel von einer anderen Entität vererbt und erweitert
⇒ Existenzabhängig von einem anderen Entitätstypen
Entitätstyp und Beziehung doppelt umrahmen
[[
{ _e: "Anbieter", pos: [20, 80],
attributes: [
{ _a:"Anbieternr.", options:["primary"], pos: [5, 5] },
{ _a:"Anbietername", pos: [120, 5] }
]
},
{ _e: "Handytarif", pos: [350, 80], options: ["weak"],
attributes: [
{ _a:"Tarifbezeichn.", options:["extending_primary"], pos: [300, 5] },
{ _a:"Datenvolumen", pos: [417, 5]},
{ _a:"Preis", pos: [520, 40]}
]
}
],
[
{ _r: "hat",
_e: ["Anbieter", "Handytarif"], options: ["weak"],
card: ["1", "N"]
}
]]
Die Kombination aus Anbieternummer und Tarifbezeichnung identifiziert einen Handytarif eindeutig, z. B. Vugafon "Data Extreme".
Handytarif ist ein schwacher Entitätstyp (Weak Entity Type ). Die Tarife sind existenzabhängig vom jeweiligen Anbieter des Tarifs. Dies ist daran zu erkennen, dass sowohl Entitätstyp als auch die Beziehung zum Anbieter doppelt umrahmt sind. Zu einem Tarif muss es einen Anbieter geben. Die Tarifbezeichnung ist ein erweiternder Primärschlüssel . Sie ist eindeutig für einen bestimmten Anbieter. Es kann einen "Data Extreme"-Tarif bei mehreren Anbietern geben, aber bei jedem nur einmal.
N:M-Bez. vs. schwacher Entitätstyp
[[
{ _e: "Kunden", pos: [50, 10],
attributes: [
{ _a:"Kundennr", options:["primary"], pos: [10, 85] },
{ _a:"...", pos: [140, 85] }
]
},
{ _e: "Produkte", pos: [730, 10],
attributes: [
{ _a:"Produktnr", options:["primary"], pos: [690, 85] },
{ _a:"...", pos: [810, 85] }
]
},
{ _e: "Bewertungen", pos: [390, 10], options: ["weak"],
attributes: [
{_a:"Sterne", pos: [340, 100] },
{_a:"Text", pos: [480, 100] } ]
}
],
[
{ _r: "schreiben",
_e: ["Kunden", "Bewertungen"], options: ["weak"],
card: ["1", "N"]
},
{ _r: "für",
_e: ["Bewertungen", "Produkte"], options: ["weak"],
card: ["N", "1"]
}
]]
Der unten dargestellte schwache Entitätstyp "Bewertungen" hat keine Primärschlüssel-erweiternden Attribute, aber sie ist existenzabhängig vom bewertenden Kunden und dem bewerteten Produkt. Eine Bewertung wird also eindeutig identifiziert durch die entsprechende Kundennummer- und Produktnummer-Kombination. Die beiden auf dieser Folie dargestellten ER-Diagramme sind in ihrer aktuellen Version absolut äquivalent und modellieren genau das gleiche. Die untere Version bietet jedoch mehr Erweiterungsmöglichkeiten (siehe nächste Folie).
N:M-Bez. vs. schwacher Entitätstyp
[[
{ _e: "Kunden", pos: [50, 10],
attributes: [
{ _a:"Kundennr", options:["primary"], pos: [10, 85] },
{ _a:"...", pos: [140, 85] }
]
},
{ _e: "Produkte", pos: [730, 10],
attributes: [
{ _a:"Produktnr", options:["primary"], pos: [690, 85] },
{ _a:"...", pos: [810, 85] }
]
},
{ _e: "Bewertungen", pos: [390, 10], options: ["weak"],
attributes: [
{_a:"Sterne", pos: [340, 100] },
{_a:"Text", pos: [480, 100] } ]
}
],
[
{ _r: "schreiben",
_e: ["Kunden", "Bewertungen"], options: ["weak"],
card: ["1", "N"]
},
{ _r: "für",
_e: ["Bewertungen", "Produkte"], options: ["weak"],
card: ["N", "1"]
},
{ _r: "gefallen", pos: [80, 161],
_e: ["Kunden", "Bewertungen"],
card: ["N", "M"]
}
]]
Dadurch, dass die Bewertungen nun ein Entitätstyp sind, kann dieser nun an Beziehungen teilnehmen und Subtypen (siehe später in diesem Kapitel) haben. Kunden können bei einer Bewertung auf "gefällt mir" klicken. Die "gefallen"-Beziehung ist naturlich nicht doppelt umrahmt. Nicht die Kunden, denen eine Bewertung gefallen identifizieren diese, sondern diejenigen, die sie schreiben (und das bewertete Produkt). Löscht ein Kunde seinen Account, darf es keine Bewertungen mehr geben, von denen der Kunde Autor ist, aber es darf weiterhin Bewertungen geben, für die er oder sie ein Like abgegeben hat. In der Modellierung mit der "bewertet"-Beziehung (vorherige Folie oben) ist es nicht möglich, Bewertungslikes zu modellieren.
N:M- vs. zwei 1:N-Beziehungen
[[
{ _e: "Gäste", pos: [150, 100],
attributes: [
{ _a:"Kundennr", options:["primary"], pos: [89, 25] },
{ _a:"Tischnr", pos: [245, 25] }
]
},
{ _e: "Getränke", pos: [530, 100],
attributes: [
{ _a:"Bezeichnung", pos: [475, 25], options:["primary"] },
{ _a:"Preis", pos: [627, 25]}
]
}
],
[
{ _r: "trinken",
_e: ["Gäste", "Getränke"],
card: ["N", "M"]
}
]]
Besser:
[[
{ _e: "Gäste", pos: [20, 100],
attributes: [
{ _a:"Kundennr", options:["primary"], pos: [5, 25] },
{ _a:"Tischnr", pos: [120, 25] }
]
},
{ _e: "Bestellpositionen", pos: [350, 100], options: ["weak"],
attributes: [
{ _a:"Positionsnr.", options:["extending_primary"], pos: [375, 25] }
]
},
{ _e: "Getränke", pos: [750, 100],
attributes: [
{ _a:"Bezeichnung", pos: [695, 25], options:["primary"] },
{ _a:"Preis", pos: [847, 25]}
]
}
],
[
{ _r: "geben auf",
_e: ["Gäste", "Bestellpositionen"], options: ["weak"],
card: ["1", "N"]
},
{ _r: "von",
_e: ["Bestellpositionen", "Getränke"],
card: ["N", "1"]
}
]]
Gäste bestellen in einer Bar Getränke. Ein Gast kann mehrere Getränke trinken (Kunde Nr. 5 trinkt Rotwein und Mineralwasser) und ein Getränk kann von mehreren Gästen bestellt werden (Kunden 7 und 8 trinken Weißwein). Das Problem hier ist jedoch, dass niemand ein bestimmtes Getränk mehrfach trinken kann. Wir lösen das Problem, indem ein Kunde mehrere Bestellpositionen aufgibt. Jede Position erhält eine für den Kunden eindeutige Nummer und enthält nur ein Getränk. Bestellt ein Kunde 2x Rotwein und 1x Mineralwasser, werden dazu drei Bestellpositionen erfasst.
Ternäre Beziehungen
13
Bisher: Beziehungs-Grad = 2 (binäre Beziehung)
Grad: Anzahl der teilnehmenden Entitätstypen
Ternäre Beziehung: Grad = 3
[[
{ _e: "Kunden", pos: [150, 100],
attributes: [
{ _a:"Kundennr", options:["primary"], pos: [89, 13] },
{ _a:"Name", pos: [245, 13] }
]
},
{ _e: "Tarife", pos: [530, 100],
attributes: [
{ _a:"Bezeichnung", pos: [475, 25], options:["primary"] },
{ _a:"Mindestlaufzeit", pos: [599, 25]},
{ _a:"Preis", pos: [698, 71]}
]
},
{ _e: "Fitnessstudios", pos: [334, 277],
attributes: [
{ _a:"Strasse", pos: [205, 212], options:["primary"] },
{ _a:"Hausnummer", pos: [205, 275], options:["primary"] },
{ _a:"Ort", pos: [510, 274], options:["primary"] }
]
}
],
[
{ _r: "buchen",
_e: ["Kunden", "Tarife", "Fitnessstudios"],
card: ["N", "1", "M"],
attributes: [{_a:"Datum", pos: [462, 195]}]
}
]]
Ternäre Beziehungen
Ein Kunde kann in einem Fitnessstudio nur einen Tarif buchen
Ein Kunde kann einen Tarif in vielen Studios buchen
Ein Tarif kann in einem Studio von vielen Kunden gebucht werden
Auch hier beginnt man zum korrekten Annotieren der Kardinalitäten den Satz wieder mit "Ein...ein...".
Ternäre vs. drei binäre Beziehungen
[[
{ _e: "Kunden", pos: [150, 100],
attributes: [
{ _a:"Kundennr", options:["primary"], pos: [89, 13] },
{ _a:"Name", pos: [245, 13] }
]
},
{ _e: "Tarife", pos: [530, 100],
attributes: [
{ _a:"Bezeichnung", pos: [475, 25], options:["primary"] },
{ _a:"Mindestlaufzeit", pos: [599, 25]},
{ _a:"Preis", pos: [698, 71]}
]
},
{ _e: "Fitnessstudio", pos: [334, 277],
attributes: [
{ _a:"Strasse", pos: [205, 250], options:["primary"] },
{ _a:"Hausnummer", pos: [205, 320], options:["primary"] },
{ _a:"Ort", pos: [510, 274], options:["primary"] }
]
}
],
[
{ _r: "buchen",
_e: ["Kunden", "Tarife"],
card: ["N", "1"],
attributes: [{_a:"Datum", pos: [364, 27]}]
},
{ _r: "angemeldet bei", pos: [284, 188],
_e: ["Kunden", "Fitnessstudio"],
card: ["N", "M"]
},
{ _r: "buchen",
_e: ["Kunden", "Tarife"],
card: ["N", "1"],
attributes: [{_a:"Datum", pos: [364, 27]}]
},
{ _r: "gilt in", pos: [452, 193],
_e: ["Fitnessstudio", "Tarife"],
card: ["N", "M"]
}
]]
Ein Kunde bucht stets nur einen Studio-übergreifenden Tarif.
Ein Kunde kann bei vielen Studios angemeldet sein
Ein Tarif ist in vielen Fitnessstudios gültig
Diese Lösung ist nicht weniger oder mehr richtig als die Lösung mit der ternären Beziehung auf der vorherigen Folie, aber sie modelliert eine komplett andere Miniwelt.
Generalisierung
13
Spezialisierung, Vererbung
Attribute, Primärschlüssel und Beziehungen des Super-Typen werden an die Sub-Typen vererbt.
"is-a"-Pfeil im ER-Diagramm
[[
{ _e: "Kunden", pos: [110, 100],
attributes: [
{ _a:"Kundennr", options:["primary"], pos: [15, 10] },
{ _a:"Name", pos: [130, 10] },
{ _a:"E-Mail", pos: [250, 10] }
]
},
{ _e: "Privatkunden", pos: [10, 250], isa: {_e:"Kunden"},
attributes: []},
{ _e: "Geschäftskunden", pos: [200, 250], isa: {_e:"Kunden"},
attributes: []}
],
[
]]
Welche Attribute hat ein Privatkunde?
Nur Kundennr
Keine
Kundennr, Name, E-Mail
Kundennr, Name, E-Mail, Type-Tag
https://frage.space
Der Entitätstyp "Kunden" hat zwei Sub-Typen "Privatkunden" und "Geschäftskunden". In unserer Datenbank können wir also für jeden Kunden speichern, ob er einfach nur Kunde ist, oder aber auch Geschäftskunde und Privatkunde. Es gibt Notationen, in der Überlappungen (Mehrklassenzugehörigkeit) und abstrakte Typen (nicht instanziierbar) modelliert werden können. In unserer Notation ist eine Entität stets nur eine direkte Instanz von einem Entitätstypen, und damit implizit auch Instanz von dessen Super-Typen. Jeder Privatkunde ist also auch Kunde. Subtypen können auch wieder Subtypen haben, sodass sich komplexe Typhierarchien modellieren lassen.
Generalisierung
[[
{ _e: "Kunden", pos: [110, 100],
attributes: [
{ _a:"Kundennr", options:["primary"], pos: [15, 10] },
{ _a:"Name", pos: [130, 10] },
{ _a:"E-Mail", pos: [250, 10] }
]
},
{ _e: "Privatkunden", pos: [10, 250], isa: {_e:"Kunden"},
attributes: [ {_a:"Bonuspunke", pos: [35, 334]} ]},
{ _e: "Geschäftskunden", pos: [200, 250], isa: {_e:"Kunden"},
attributes: [ { _a:"USt-IdNr.", pos: [225, 334]} ]},
{ _e: "Produkte", pos: [730, 100],
attributes: [
{ _a:"Produktnr", options:["primary"], pos: [690, 10] },
{ _a:"...", pos: [810, 10] }
]
}
],
[
{ _r: "bewerten",
_e: ["Kunden", "Produkte"],
card: ["N", "M"],
attributes: [ {_a:"Sterne", pos: [390, 10] }, {_a:"Text", pos: [500, 10] } ]
},
{ _r: "verkaufen", pos: [538, 189],
_e: ["Geschäftskunden", "Produkte"],
card: ["1", "N"]
}
]]
Das ER-Diagramm wurde erweitert um Subtypen-spezifische Attribute und Beziehungen. Nur Geschäftskunden können Produkte verkaufen, aber alle Kunden können sie bewerten. Privatkunden sammeln Bonuspunkte und für Geschäftskunden wird die Umsatzsteuernummer vermerkt.
Notationsformen
https://de.wikipedia.org/wiki/Entity-Relationship-Modell
Wir verwenden die Chen-Notation
Nicht anpassbar in Chen:
Es gibt Orte ohne Personen
Es gibt Personen ohne Ort
Kapitelzusammenfassung
DB-Entwurf mit ER-Diagrammen
Entitätstypen, Attribute, Beziehungen
Primärschlüssel
Schwache Entitätstypen
Ternäre Beziehungen
Generalisierung
Krähenfuß-Notation
Kochrezept: ER-Diagramm erstellen
Text lesen; beim Lesen markieren; wichtige Zusatzinfos unterstreichen
Rosa : Entitätstypen
Gelb : Attribute
Grün : Beziehungen
Das Markierte in ER-Diagramm überführen
Nochmals Text lesen und ER-Diagramm überprüfen
Letzte Überprüfung mittels Checkliste (nächste Folie)
Checkliste: ER-Diagramm erstellen
Sind alle Kardinalitäten an Beziehungen?
Kardinalitäten richtig herum?
Gibt es überflüssige Entitätstypen?
Hat jeder Entitätstyp einen Primärschlüssel?
Müssen manche Entitätstypen schwach sein?
Ist die entsprechende Beziehung doppelt umrahmt?
Sind erweiternde Primärschlüssel unterstrichelt?
Sind Generalisierungen korrekt modelliert?
Beispielaufgabe
Eine Bibliothek möchte eine Datenbank einsetzen, um Bücher zu speichern. Jedes Buch hat eine eindeutige ISBN, mehrere Autoren, und einen Titel. Bücher sind von einem Verlag. Von einem Verlag kann es mehrere Bücher geben. Jeder Verlag wird durch eine Verlags-ID identifiziert und hat einen Namen sowie einen Ort.
Beispielaufgabe
Eine Bibliothek möchte eine Datenbank einsetzen, um Bücher zu speichern. Jedes Buch hat eine eindeutige ISBN , mehrere Autoren , und einen Titel . Bücher sind von einem Verlag . Von einem Verlag kann es mehrere Bücher geben . Jeder Verlag wird durch eine Verlags-ID identifiziert und hat einen Namen sowie einen Ort .
[[
{ _e: "Bücher", pos: [150, 100],
attributes: [
{ _a:"ISBN", options:["primary"], pos: [50, 13] },
{ _a:"Autoren", options: ["multi"], pos: [175, 13] },
{ _a:"Titel", pos: [295, 13] }
]
},
{ _e: "Verlage", pos: [530, 100],
attributes: [
{ _a:"Verlags-ID", pos: [475, 25], options:["primary"] },
{ _a:"Name", pos: [595, 25] },
{ _a:"Ort", pos: [702, 63] }
]
}
],
[
{ _r: "sind von",
_e: ["Bücher", "Verlage"],
card: ["N", "1"]
}
]]
Falsche Lösung
[[
{ _e: "Bibliothek", pos: [30, 100],
attributes: [
]
},
{ _e: "Datenbank", pos: [180, 300],
attributes: [
]
},
{ _e: "Bücher", pos: [350, 100],
attributes: [
{ _a:"ISBN", pos: [250, 13] },
{ _a:"Autoren", options: ["multi"], pos: [375, 13] },
{ _a:"Titel", pos: [495, 13] }
]
},
{ _e: "Verlage", pos: [730, 100],
attributes: [
{ _a:"Verlags-ID", pos: [675, 25], options:["primary"] },
{ _a:"Name", pos: [795, 25] }
]
}
],
[
{ _r: "sind von",
_e: ["Bücher", "Verlage"],
card: ["1", "N"]
},
{ _r: "setzt ein",
_e: ["Bibliothek", "Datenbank"],
card: ["1", "1"]
},
{ _r: "verwaltet",
_e: ["Datenbank", "Bücher"],
card: ["", ""]
}
]]
In diesem ER-Diagramm fehlen Kardinalitäten an einer Beziehung, an einer anderen Beziehung sind sie falsch herum. Dem Entitätstyp "Bücher" fehlt der Primärschlüssel. Die Entitätstypen "Bibliothek" und "Datenbank" sind völlig falsch. Wir speichern viele Bücher und viele Verlage, aber wir speichern keine Bibliotheken und Datenbanken! Man erkennt überflüssige Entitätstypen auch daran, dass einem dazu keine Attribute einfallen.