pip install dbis-er-diagram
In der Vorlesung haben Sie das Relationale Datenmodell kennengelernt. ER-Diagramme bieten ein Modell zur Darstellung von EntitÀten und deren Relationen.
Dieses Blatt gibt einen kurzen Ăberblick ĂŒber die Elemente des Entity-Relationship-Modells (ER-Modell) und eine EinfĂŒhrung in ein von uns entwickeltes Python-tool, welches euch das digitale Zeichnen von ER-Diagrammen erleichtern soll.
Die folgende Zelle importiert das Python Modul und ermöglicht dessen Nutzung innerhalb des Notebooks:
from erdiagram.ER import ER
Diese Zeile muss einmalig am Anfang des Notebooks ausgefĂŒhrt werden.
Neue EntitĂ€t zum Graphen hinzufĂŒgen:
add_node()
Entities sind Objekte - konkrete oder abstrakte GegenstĂ€nde oder Wesen, welche sich von anderen Entities unterscheiden. Beispiele hierfĂŒr sind Person, Auto, Kunde, Buch, etc.
Entity-Typen sind Mengen von Entities, welche die gleichen Attribute besitzen. Beispiele fĂŒr Entity-Typen sind Personen, Autos, Kunden, etc.
Entity-Typen werden in ER-Diagrammen durch Rechtecke dargestellt.
Der Befehl um einen Entity-Typen zum Diagramm hinzuzufĂŒgen ist add_node("Entity Name")
add_node(label, isMultiple = False, isWeak = False)
-
label(str)
: Knotenbezeichnung -
isMultiple(bool)
: Ist die KardinalitÀt des Knotens mehrfach oder singulÀr? -
isWeak(bool)
: Ist dies ein schwacher Knoten?
# Initialisiere ein neues ER-Diagramm und speichere die Referenz in der Variable g
g = ER()
# FĂŒge einen neuen Knoten mit dem Namen Buch hinzu
g.add_node("Buch")
# Zeichne das Diagramm
g.display()
Neues Attribut zu einer EntitĂ€t im Graphen hinzufĂŒgen
add_attribute()
Alle Mitglieder eines Entity-Typs werden durch eine Menge charakterisierender Eigenschaften (Attributes) beschrieben. Beispiele hierfĂŒr sind Farbe, Gewicht und Preis beim Entity-Typ Teile. Die Werte eines Attributes stammen normalerweise aus Wertebereichen wie INTEGER
, REAL
, STRING
, etc. aber auch strukturierte Werte wie Listen, BĂ€ume, usw. sind vorstellbar.
Ein SchlĂŒssel ist eine minimale Menge von Attributen, deren Werte das zugeordnete Entity eindeutig innerhalb aller Entities seines Typs identifiziert.
Attribute werden im ER-Diagramm durch Ellipsen dargestellt:
- Attribute sind ĂŒber ungerichtete Kanten mit dem zugehörigen Entity-Typ verbunden.
- SchlĂŒssel-Attribute (primary key) werden (in der Regel) unterstrichen.
Der Befehl um ein Attribut zu einem Entity-Typen hinzuzufĂŒgen ist add_attribute("Entity-Type name", "Attribute name")
.
Um ein Attribut als SchlĂŒssel-Attribut zu kennzeichnen, muss auĂerdem der Parameter isPK
auf True
gesetzt werden.
g.add_attribute( nodeLabel, attrLabel,
isPK = False, isMultiple = False,
isWeak = False, composedOf=[])
-
nodeLabel(str)
: Bezeichnung des ĂŒbergeordneten Knotens -
attrLabel(str)
: Bezeichnung des Attributs -
isPK(bool)
: Ist dieses Attribut der PrimĂ€rschlĂŒssel? -
isMultiple(bool)
: Ist die KardinalitÀt des Knotens mehrfach oder singulÀr? -
isWeak(bool)
: Ist dies ein schwaches Attribut? -
composedOf(list)
: Liste der Attribute, aus denen sich dieses Attribut zusammensetzt
g = ER()
g.add_node("Buch")
# Attribute hinzufĂŒgen
g.add_attribute("Buch", "Titel")
g.add_attribute("Buch", "Seitenanzahl")
# Die ISBN beschreibt ein Buch eindeutig und ist daher ein SchlĂŒssel-Attribut
g.add_attribute("Buch", "ISBN", isPK=True)
g.display()
Ein Attribut kann aus anderen Attributen bestehen. Ein Beispiel hierfĂŒr ist eine Addresse, welche aus StraĂe + Hausnummer, Postleitzahl und Ort besteht.
Unterattribute werden mit ungerichteten Kanten mit dem zusammengesetzten Attribut verbunden.
Um ein zusammengetztes Attribut zu erstellen muss beim Erstellen des Attributs eine Liste von Unterattributen als Parameter composedOf
ĂŒbergeben werden.
Eine Adresse besteht aus einer StraĂe + Hausnummer, einer PLZ und einem Ort.
g = ER()
g.add_node("Person")
g.add_attribute("Person", "Adresse",
composedOf=["StraĂe + Nr.", "PLZ", "Ort"])
g.display()
Ein (mehrwertiges) Attribut kann eine Menge von Werten enthalten. Ein Beispiel hierfĂŒr ist das Autor Attribut des Entity-Typ Buch, da ein Buch von mehreren Autoren geschrieben sein kann.
Ein mehrwertiges Attribut wird als Ellipse mit doppelter Umrandung dargestellt.
Um ein Attribut als mehrwertig zu kennzeichnen, muss der Parameter is_multiple
auf wahr gesetzt werden.
Ein Buch kann von mehreren Autoren geschrieben werden.
NatĂŒrlich nehmen wir in diesem Beispiel an, dass "Autor" keine EntitĂ€t ist, sondern lediglich ein Attribut der EntitĂ€t "Buch".
g = ER()
g.add_node("Buch")
g.add_attribute("Buch", "Autoren", isMultiple=True)
g.display()
Neue Beziehung (=Relation) zwischen zwei EntitĂ€ten hinzufĂŒgen
add_relation()
Oft stehen zwei oder mehr Entity-Typen in Beziehung zueinander. Beziehungen werden im ER-Diagramm durch Rauten dargestellt und können ebenfalls Attribute haben.
FĂŒr die KardinalitĂ€tsrestriktionen wurden in der Vorlesung zwei Notationen vorgestellt: die 1:n-Notation
und die (min,max)-Notation
.
Hierdurch können zusÀtzlich zur dargestellten Relation KardinalitÀten angegeben werden um darzustellen, in welcher Anzahl die EntitÀten des einen Entity-Typen mit welcher Anzahl von EntitÀten des anderen Entity-Typen in Beziehung stehen.
Diese KardinalitÀten werden im ER-Diagramm an die Kanten zwischen Entity-Typ und Relation geschrieben.
Der Befehl um eine Beziehung hinzuzufĂŒgen ist add_relation("From Entity-Type", "Relation name", "To Entity-Type", "n", "m")
.
g.add_relation(fromNodeLabel, relationLabel,
toNodeLabel, fromEdgeLabel,
toEdgeLabel, isWeak=False)
-
fromNodeLabel(str)
: Bezeichnung des "from"-Knotens -
relationLabel(str)
: Label der Relation -
toNodeLabel(str)
: Label des "to"-Knotens -
fromEdgeLabel(str)
: Label der "from"-Kante -
toEdgeLabel(str)
: Beschriftung der "to"-Kante -
isWeak(bool)
: Ist dies eine schwache Beziehung?
Mehrere Patienten besuchen mehrere Ărzte. Zu jedem Besuch wird ein Datum gespeichert.
g = ER()
g.add_node("Arzt")
g.add_node("Patient")
g.add_relation("Patient", "besucht", "Arzt", "m", "n")
g.add_attribute("besucht", "Datum")
g.display()
Es können auch drei oder mehr Entity-Typen in Beziehung zueinander stehen.
Um weitere Entity-Typen einer Beziehung hinzuzufĂŒgen, kann der erste Parameter des add_relation
Befehls leer ("") gelassen werden.
Ein Professor prĂŒft einen Studenten ĂŒber eine Vorlesung.
g = ER()
g.add_node("Student")
g.add_node("Vorlesung")
g.add_node("Professor")
g.add_relation("Professor", "prĂŒft", "Student", "prĂŒft", "wird geprĂŒft")
g.add_relation("", "prĂŒft", "Vorlesung", "", "ĂŒber")
g.display()
Ein schwacher Entity-Typ ist von der Existenz des ĂŒbergeordneten Entity-Typs abhĂ€ngig.
Schwache EntitĂ€tstypen werden im ER-Diagramm durch einen doppelten Rahmen um die Beziehung und eine doppelte Kante zwischen dem Beziehungsknoten, dem EntitĂ€tsknoten und der schwachen EntitĂ€t gekennzeichnet. AuĂerdem werden die SchlĂŒssel von schwachen Entity-Typen gestrichelt unterstrichen.
Hierzu muss in allen drei Befehlen (add_node
, add_relation
, add_attribute
) der Parameter isWeak
auf True
gesetzt werden.
Ohne HörsaalgebÀude kann es keine SeminarrÀume geben.
g = ER()
g.add_node("HörsaalgebÀude")
g.add_node("Seminarraum", isWeak=True)
g.add_relation("HörsaalgebÀude", "liegt in", "Seminarraum", "(0,n)", "(1,1)", isWeak=True)
g.add_attribute("Seminarraum", "RaumNr", isPK=True, isWeak=True)
g.display()
Es kann Vererbungsbeziehungen (isA) zwischen Entity-Typen und spezialisierten Entity-Typen geben. Diese werden im ER-Diagramm als umgedrehte Dreiecke mit einer ungerichteten Kante zum allgemeinen Entity-Typen und einer oder mehreren gerichteten Kanten zu den spezialisierten Entity-Typen dargestellt.
Es gibt unterschiedliche Formen dieser Vererbungsbeziehungen:
-
Disjunkt
- Spezialisierungen sind disjunkt (ein Angestellter kann nicht Assistent und Professor sein)
- Pfeile zeigen in Richtung der Spezialisierung
-
Nicht disjunkt
- Spezialisierungen sind nicht disjunkt (Eine Person kann Angestellter und Student sein)
- Pfeile Zeigen in Richtung der Generalisierung
-
Total (t)
- Die Dekomposition der Generalisierung ist vollstÀndig (Es gibt entweder wissenschaftliche oder nicht wissenschaftliche Mitarbeiter)
- Wird durch âtâ neben der isA Beziehung dargestellt
-
Partiell (p)
- Die Vereinigung der Spezialisierung ist eine echte Untermenge der Generalisierung
- Wird durch âpâ neben der isA Beziehung dargestellt
Der Befehl um eine isA Beziehung zum ER-Diagramm hinzuzufĂŒgen ist add_is_a("Generalisation", ["Specialisation1","Specialisation2"], "p or t (partial or total)", isDisjunct=True/False)
g.add_is_a(superClassLabel, subclassParam,
superLabel='', subLabel='',
isDisjunct=True)
-
superClassLabel(str)
: Bezeichnung des Oberklassenknotens ("parent"/"superclass") -
subclassParam(str oder Liste von str)
: Label des/der Unterklassenknoten(s) ("child"/"subclass") -
superLabel(str)
: Ist die Beziehung partiell oder total? ("p" oder "t" - geschrieben auf der Kante zur Oberklasse) -
subLabel(str)
: Ist die Beziehung partiell oder total? ("p" oder "t" - wird auf die Kante zur Unterklasse geschrieben) -
isDisjunct(bool)
: Sind die Elemente dieser Relation disjunkt?
g = ER()
g.add_node("Arzt")
g.add_node("Assistenzarzt")
g.add_node("Oberarzt")
g.add_node("Chefarzt")
g.add_is_a("Arzt", ["Assistenzarzt", "Oberarzt", "Chefarzt"], "p", isDisjunct=True)
g.display()
Der folgende Code erstellt die Relation
- Student(MatrNr, Name, Semester, Adresse)
g = ER()
g.add_node('Student')
g.add_attribute('Student', 'MatrNr', isPK = True)
g.add_attribute('Student', 'Name')
g.add_attribute('Student', 'Semester', isMultiple = True)
g.add_attribute('Student', "Adresse", composedOf = ["Stadt", "StraĂe", "PLZ"])
g.display()
Der folgende Code erstellt folgende...
- Student(MatrNr)
- Vorlesung(VorlNr)
- Hört(MatrNr, VorlNr)
Der folgende Code erstellt folgende...
- Angestellter(PersNr, Name)
- Professor(PersNr, Rang, Raum)
- Assistent(PersNr, Fachgebiet)
- Professor[PersNr]
$\subseteq$ Angestellter[PersNr] - Assistent[PersNr]
$\subseteq$ Angestellter[PersNr]
- Professor[PersNr]
$\cap$ Assistent[PersNr] =$\emptyset$
Professor und Assistent sind disjunkt (ein Assistent kann nicht Professor sein).
Die Unterscheidung zwischen "total" und "partiell" wird (manuell) durch den Parameter super_label
gesteuert.
g = ER()
g.add_node('Angestellter')
g.add_attribute('Angestellter', 'PersNr', isPK = True)
g.add_attribute('Angestellter', 'Name')
g.add_node('Professor')
g.add_node('Assistent')
g.add_is_a('Angestellter', ['Professor', 'Assistent'], superLabel = 'p', isDisjunct = True)
g.display()