Ich glaube, wir fangen an mit der Übung.
Heute steht Übungsblatt Nummer 5 auf dem Programm und da geht es um
SQL.
Das Übungsblatt ist hoffentlich dieses Mal richtig lesbar gewesen.
Ich habe zumindest keine Rückmeldung gekriegt, dass es da Probleme
gäbe.
Deswegen nehme ich mal an, dass es alles geklappt hat jetzt.
Das Übungsblatt Nummer 6 wird nächste Woche gleich besprochen.
Wir haben jetzt nächste Woche das 6.
Übungsblatt und die Woche darauf das 7.
Übungsblatt.
Das Übungsblatt Nummer 6 kommt heute noch raus.
Es ist noch nicht auf dem Netz, wird also erst dann noch
veröffentlicht.
Und da geht es dann um Datenbankentwurf und Normalisierung.
Heute aber zu SQL und da steigen wir einfach gleich ein.
Da gibt es eine sehr umfangreiche erste Aufgabe, die so verschiedene
Aspekte von SQL gleich mal behandelt und wo man sich dann noch mal
vertiefen kann und sich anschauen kann, ob man alles verstanden hat.
Wir haben also hier eine Krankenhausdatenbasis mit Krankheit, Patient,
Arzt und dann diese leitet an und behandelt Relationen, in denen man
sieht, dass da wohl Beziehungen mit ausgedrückt werden.
Dass nämlich ein Patient an einer Krankheit leidet und dass ein
Patient von einem Arzt behandelt wird.
Jetzt steigen wir erstmal ganz einfach ein.
Erstmal war die Frage, wie sieht denn so ein SQL-Ausdruck aus?
Für eine relativ einfache Frage, wobei hier natürlich auch beliebig
viele Möglichkeiten gegeben sind, wie man das formuliert.
Hier sollte eine ohne innere Selektanweisung, also ohne Schachtelung
durchgeführt werden.
Das hat dann auch einen Grund, dass wir anschließend auf den
Relationen -Algebraischen Ausdruck wechseln wollten.
Gesucht sind alle Namen männlicher Patienten, die an Diabetes leiden
und vom Arzt, dessen Name Dr. Schmidt ist, behandelt werden.
Also recht einfach.
Wie gehen wir vor?
Wir fangen an mit einem Select, geben dann die Relationen an, von
denen wir Informationen bekommen und geben dann noch die
entsprechenden Bedingungen an, die Tupel, die wir auswählen, erfüllen
sollen.
Beim Select geht es ja darum, was ist denn gesucht.
Die Namen von Patienten sind gesucht.
Also schauen wir uns mal an, wo sind denn die Namen von Patienten hier
oben drin enthalten.
Es gibt hier einen Namen, das ist aber der vom Arzt, aber hier beim
Patienten gibt es also auch einen Namen.
Das dürfte wohl der richtige sein.
Dann schreiben wir doch hier schon mal rein, dass wir den Patienten
wohl brauchen, denn dieser Name kommt nur dort vor.
Und setzen wir gleich noch ein Alias.
Das muss nicht unbedingt sein, aber wir könnten auch ohne auskommen.
Aber das brauchen wir auf jeden Fall.
Patient, die Relation.
Und dann sagen wir, was möchten wir am Schluss haben.
Wir möchten P. Name als Ergebnis haben.
Aber nicht von allen Patienten, sondern, okay, die sollen ja eine
bestimmte Krankheit haben, nämlich an Diabetes leiden.
Und woran ein Patient leidet, das erkennt man an dieser Relation
leidet an, denn dort ist als einzige der Krankheitsname drin
enthalten.
Also brauchen wir wohl auch noch einen Krankheitsnamen.
Die Relation leidet an und dann bekommen wir den Krankheitsnamen.
Gut, jetzt wissen wir, also diese Relation leidet an.
Da haben wir auf jeden Fall eine Einschränkung, die darauf beruht,
nämlich, dass der Krankheitname gleich Diabetes ist.
Das war ja unsere Forderung.
Gut, das reicht jetzt noch nicht aus.
Jetzt habe ich hier praktisch leidet an noch nicht geknüpft an den
Patienten.
Ich habe nur gesagt, ich wähle mir aus leidet an nur die Tubel raus,
die die Krankheitsnamen gleich Diabetes haben.
Aber ich habe noch keine Beziehung zu den Patienten hergestellt an der
Stelle.
Das heißt, im Relationenausdruck würde ich jetzt eine Joint-Operation
durchführen.
In diesem Fall, im SQL-Ausdruck, muss ich jetzt hier also die
Gleichheitsbedingung, die eine Joint-Operation beinhaltet, direkt
hinschreiben in die Wehrklausel.
Ich mache das jetzt hier an dem einen Beispiel etwas ausführlicher,
gehe nachher dann nur auf die Besonderheiten ein bei den nächsten
Select -Anweisungen.
Also wenn es ein paar langweilig wird jetzt, weil sie das sowieso alle
schon erledigt haben, wir sind gleich durch und dann geht es etwas
flotter voran.
Also müssen wir jetzt hier zwischen Patient und leidet an eine
Beziehung herstellen, nämlich diese Joint-Verbindung.
Und die können wir ja, das sehen wir hier an der Stelle, wenn man die
Relationen betrachtet, die können wir wohl darüber herstellen, dass
wir hier eine Patientennummer haben.
Und das soll eben der Fremdschlüssel sein, der Relation Patient und
soll damit den Patienten identifizieren, der an dieser Krankheit
leidet.
Das heißt, ich mache jetzt hier eine Joint-Verbindung zwischen Nummer
vom Patienten und der Patientennummer, die in dieser Relation leidet
an drin enthalten ist.
Also schreibe ich einfach hin, L.Patientnummer gleich P.Nummer.
So, jetzt habe ich die Verbindung zwischen beiden Relationen.
So, jetzt fehlt uns noch der Arzt.
Es spielt also noch ein Arzt eine Rolle und dieser Arzt soll den Namen
Dr. Schmidt haben und der soll den Patienten behandeln.
Die drei Dinge wissen wir.
Jetzt schauen wir uns mal den Arzt an.
Der Arzt, der hat, die Relation Arzt hat eine Nummer, das heißt, der
ist Schlüssel.
Der Name, den brauchen wir wohl, weil wir müssen da ja eine Selektion
betreiben nach Dr. Schmidt.
Und ein Fachgebiet, das interessiert uns jetzt nicht weiter, aber der
Name interessiert uns.
Jetzt schauen wir uns noch an, behandelt gibt es noch und wir brauchen
ja auch noch die Beziehung, das steht hier praktisch, zwischen dem
Arzt und dem Patienten.
Und die ist genau in dieser Relation behandelt drin enthalten.
Da wird nämlich der Patient über die Patientnummer identifiziert als
Fremdschlüssel, mit dem Arzt identifiziert über die Arztnummer in
Beziehung gesetzt.
Das heißt, wir brauchen auch noch diese Relation.
Und da gehen wir jetzt genauso vor.
Jetzt können wir erstmal beispielsweise diese Selektionsbedingungen
mit dem Dr. Schmidt einfügen.
Das wäre also jetzt in der Relation Arzt.
Und da bräuchte ich jetzt Arzt.Name.
Ah ja, hier fehlt uns natürlich der Arzt.
Den brauchen wir.
Und wir brauchen noch behandelt.
Dann kommt hier A.Name gleich Dr. Schmidt.
Und dann kommt noch unsere Joint-Verbindung zwischen,
ja noch nicht.
Wir müssen den Arzt ja in irgendeiner Form noch in Beziehung setzen zu
dem Patienten.
Oder zu den Krankheiten, in dem Fall zu dem Patienten.
Und das erfolgt ja über diese Behandelt-Relation.
Also an der Stelle haben wir eine Extra-Relation, in der die Beziehung
zwischen Arzt und Patient enthalten ist.
Das heißt, wenn ich jetzt hier dann reingehe, habe ich noch diese
Behandelt -Relation.
Ja, jetzt muss ich also hier noch Zusammenhang zwischen Patient, Arzt
und Behandelt, muss hier noch irgendwie rein.
Das heißt Zusammenhang.
Okay, das wird wieder ein bisschen umfangreicher.
Und da gucken wir uns jetzt gleich mal auf der nächsten Folie an, wo
ich das jetzt hier vorbereitet habe.
Also was wir schon haben, war das hier und das hier.
Und was wir auch schon haben, war das hier.
Und jetzt müssen wir ja noch diese Beziehung herstellen zwischen dem
behandelnden Patienten und dem behandelnden Arzt.
Und das passiert über diese Bedingung hier.
Patient Punkt Nummer ist gleich behandelt Punkt Patient Nummer.
Da wird Gleichheitsbedingung verlangt.
Das heißt, ich betrachte jetzt nur die Patienten, die hier behandelt
werden.
Das ist die eine Seite.
Und jetzt komme ich noch vom Arzt her.
Ich sage hier Arzt Punkt Nummer gleich Behandelt Punkt Arzt Nummer.
Auch gleich.
Das wäre das hier.
Und jetzt habe ich hier praktisch die Einschränkung, dass in dieser
Behandelt -Relation eben nur die Ärzte betrachtet werden oder die
Tubel betrachtet werden von den Ärzten, die ich ausgewählt hatte.
Das war ja gerade dieser Arzt Dr. Schmidt.
Also nur die werden in der Behandelt-Relation auch betrachtet.
Und bei den Patienten werden in der Tat nur die Patienten betrachtet.
Von der Nummer her.
Die dann, hier oben hatten wir ja schon mal eine Beziehung, die dann
an so einer Krankheit leiden.
Also die dann auch in dieser Leidet-An-Beziehung enthalten sind.
Also es sieht so einfach aus.
Man schreibt es auch relativ zügig hin.
Aber man muss sich doch vorstellen, dass da ein ganz schöner
Mechanismus dahinter steckt, wie da die Verbindungen hergestellt
werden.
Und dass da auch wirklich alles miteinander verbunden ist.
Das ist wichtig.
Es werden dann also praktisch immer, wenn ich irgendwo eine Verbindung
vergessen hätte, zum Beispiel hier Patientnummer gleich Leidet-An
-Patientnummer, dann würde das ziemlich viele Tubel liefern, die
nichts mit dem Leidet-An vielleicht zu tun hätten.
Also da muss ich aufpassen.
Da würden die Patienten dann nicht eingeschränkt werden auf diese
Krankheit.
Auf dieses Diabetes.
Also da muss ich aufpassen, dass ich überall die Beziehung habe.
Und dass diese einfache Bedingung, diese Gleichheitsbedingung hier,
hier und hier, das sind praktisch die Joint-Operationen, die man auch
behandeln muss.
So.
Da gibt es eine Frage.
Okay, gute Frage.
Das ist sehr schön, die kommt genau richtig.
Wir gucken uns gleich mal die nächste Teilaufgabe an und behandeln
dann die Antwort auf die Frage.
Das kommt nämlich dann genau.
Also das hier ist vom Prinzip her eine Umsetzung.
Wir wollen ja eine Formulierung.
Das ist genau das, was wir wissen wollten.
Das steht hier in der Anfrage.
Und genau das wollen wir eigentlich auch mit SQL erreichen.
Dass wir das formulieren, ohne uns groß Gedanken zu machen, wie das
dann nachher implementiert wird.
Und da gibt es entsprechende Mechanismen und da kommen wir gleich
drauf.
Machen wir aber einen ganz kleinen Schlenk.
Nämlich hierzu diese SQL-Anfrage.
Da wollen wir uns jetzt anschauen, wie würde denn das jetzt umgesetzt
werden in der relationalgebraischen Anfrage.
Und zwar, wenn man dieses intuitive Abarbeitungsmodell, das ja Herr
Lockermann kurz vorgestellt hat, das immer funktioniert, dass man
einfach hinschreiben kann, wenn man das zugrunde legt.
Und das ist das, worauf Sie sich jetzt gerade bezogen haben.
Also schauen wir mal an, wie das dann aussieht.
Wir gucken uns gerade nochmal kurz die Anfrage an.
Wie gehen wir da vor?
Dieses intuitive Abarbeitungsmodell sagt, die FROM-Klausel liefert uns
ein kathesisches Produkt.
Die SELECT-Klausel liefert uns die Endprojektion.
Und diese WHERE-Klausel wird dann umgesetzt in eine entsprechende
Selektionsbedingung.
Das ist so die direkte Interpretation.
Ich gehe also davon aus, ich schaue mir an, welche Relationen
beteiligt sind, bilde darüber das kathesische Produkt.
Dann habe ich noch keinerlei Zusammenhang zwischen den einzelnen
Tupeln der Relation.
Da werden alle Kombinationen mit aufgenommen.
Also ein riesiger Apparat, wenn die Relationen entsprechend groß sind,
eine sehr große Kardinalität, die wir nachher haben.
Dann anschließend führen wir über dieses kathesische Produkt diese
Selektionsbedingungen aus, die wir hier angegeben haben.
Wobei die sowohl einfache Selektionsbedingungen im Vergleich mit einem
Wert, zum Beispiel geschlechtgleich männlich, das ich vorhin vergessen
hatte übrigens, geschlechtgleich männlich enthält.
Oder sogar eine Bedingung, die uns dann nachher als Joint-Bedingung
bekannt ist.
Wenn wir das zusammenfassen mit dem Teil des kathesischen Produktes
und dieser Joint-Bedingung dann.
Mit dieser Forderung der Gleichheit von zwei Attributen, von zwei
unterschiedlichen Relationen.
Das würde uns ja eigentlich mit dem kathesischen Produkt zusammen die
Joint -Bedingung liefern.
Das war ja die Anregung, dass man da vielleicht was machen müsste.
Okay, schauen wir uns erstmal an.
So ist die prinzipielle Abfolge.
Das steht dann auch hier.
Am Schluss wollen wir nur noch den Patientnamen haben.
Das war das, was oben in der Selekt-Anweisung drin enthalten ist.
Wir haben kathesisches Produkt und das sind eben genau gerade unsere
entsprechenden Relationen drin enthalten, die wir in der Formklausel
drin reingeschrieben hatten.
Die wir also benötigen, um die Anfrage abzuarbeiten.
Und hier haben wir eine Selektionsanweisung, ein Sigma.
Das soll praktisch als Index dranhängen.
Mit dieser gesamten Bedingung, die dann auf dem Ergebnis des
kathesischen Produktes ausgeführt wird.
Das ist das, was so das intuitive Abarbeitungsmodell in der SQL
hergibt.
Da die Anfrage jetzt doch relativ viele Relationen beteiligt hat und
auch einige Bedingungen auszuführen sind, sieht es sehr unförmig
inzwischen aus.
Aber so kann man es sich immer vorstellen.
So läuft das Ganze immer ab.
Und so kann man immer schauen, ob etwas drin ist oder was die Selekt
-Anweisung eigentlich macht.
So, jetzt kommen wir an die Stelle, die ich hier nicht drin habe.
Aber das ist natürlich etwas, was genau an der Stelle jetzt reinkommt.
Das ist das intuitive Abarbeitungsmodell.
Das heißt, man kann sich vorstellen, dass die Wirkung, die Semantik so
definiert ist.
Das Datenbanksystem wird es sicherlich nicht so abarbeiten.
Da brauche ich mich als Benutzer gar nicht drum kümmern.
Ich brauche da also keine großen Anstrengungen zu machen, um jetzt zu
überlegen, wie soll ich denn jetzt diese Selekt-Anweisung vielleicht
anders formulieren.
Zum Beispiel kann ich ja in der From-Klausel auch ein Natural Join
angeben und solche Dinge.
Könnte ich die nicht vielleicht sogar schon...
Was muss ich denn da machen, damit das nicht so furchtbar aufwendig
wird und da so ein riesiges kathesisches Produkt entsteht.
Da brauche ich mich nicht drum kümmern.
Das macht das Datenbanksystem.
Es ist bekannt, was dahinter steckt.
Wir haben hier, das wäre praktisch die Umsetzung, die direkte
Umsetzung der SQL-Anweisung in Relation Allgebrauch.
Und das System, das optimiert jetzt hier drauf, auf diesem
Ausgangsausdruck.
Und kann das jetzt umwandeln in Äquivalente, aber für die Abarbeitung
günstigere Ausdrücke.
Und da kommen sicher so Sachen rein, dass man möglichst viel Join
-Operationen erstmal ausführt.
Auf jeden Fall das kathesische Produkt, wenn möglich, vermeidet, was
hier auf jeden Fall überall möglich ist.
Und Selekt-Anweisungen möglichst früh ausführt, damit die
Zwischenrelation, die ich dann nachher zum Beispiel mit Joins
zusammenführe, dass ich die dann entsprechend klein halte und so
weiter.
Solche Dinge macht das Datenbanksystem, kann das Datenbanksystem
machen.
Das ist die Optimierungskomponente, die Anfrageoptimierung.
Das heißt, die Frage von eben, das lässt mich völlig kalt.
Ich sage, ich schreibe hin, was ich haben möchte von der Semantik her,
wie das nachher am günstigsten oder ob das besonders ungünstig wäre,
wenn ich das genauso abarbeite, das interessiert mich nicht, weil da
nämlich eine Optimierung vom Datenbanksystem dahinter steckt.
Also, das kommt natürlich darauf an, wie gut der Optimierer ist, aber
das mit dem kathesischen Produkt, was Sie gerade gesagt haben, das ist
so eine Standardoptimierung, dass die auf keinen Fall gemacht wird.
Ja, also wir lernen noch in der Implementierung kurz kennen, wie die
Anfrageoptimierung läuft und da ist die Standardvorgehensweise die,
dass man solche kathesischen Produkte auf jeden Fall weg optimiert in
Richtung Joint-Operation und das, was ich vorhin gesagt habe.
Da gibt es so einen Satz von Faustregeln und die macht jeder
Optimierer.
Es sei denn, es ist ein ganz kleines, selbstgestricktes
Datenbanksystem oder sowas.
Aber alle ernstzunehmenden relationalen Datenbanksysteme machen diese
Optimierung.
Da kann ich davon ausgehen.
Es kann natürlich sein, dass manchmal, allerdings nicht bei solchen
Standardsachen, dass manchmal dann irgendwelche Besonderheiten da
sind, die ich vielleicht noch beeinflussen könnte, aber da habe ich
auch keine Chance an der Stelle dann.
Ich habe ja nur die Chance, das zu nehmen, was mir SQL erlaubt zu
formulieren und da könnte ich beispielsweise solche Joints
reinschreiben in die Frontklausel.
Das nützt mir nichts, das wird auf jeden Fall gemacht.
Diese Erweiterung da in Richtung, was man in der Frontklausel angeben
kann, das kann natürlich für den Benutzer zur Beschreibung der Anfrage
nützlich sein, wenn er in dieser Form gerne denkt.
Wenn das vorhanden ist, wenn man da in der Richtung gerne denkt und es
dann leichter formuliert, dann sollte man das auch nehmen.
Und dann gibt es natürlich Erweiterungen, zum Beispiel der Auto-Join
oder der Semi-Join, der dort formuliert werden kann, die kann ich
natürlich sonst nicht unterbringen.
Die muss ich dann so formulieren, indem ich diese Mechanismen
einsetze.
Aber diese Umsetzung, das wird nicht ausgeführt, nicht vom
Datenbanksystem ausgeführt.
Da können Sie davon ausgehen, auf jeden Fall kommt die Optimierung,
die dann eben beispielsweise, zum Beispiel kein kathesisches Produkt,
falls es möglich ist, also wie hier zum Beispiel, kein kathesisches
Produkt, wenn möglich, also sprich Umsetzung in,
also Join-Operationen werden dann erstellt, Joins, wenn möglich, wenn
da die Bedingung entsprechend im Wertteil drin ist, wird es ersetzt
und auch sonstige Optimierungen werden da gemacht.
Also das ist dieser relationalgebraische Teil der Optimierung und der
ist eigentlich Standard.
Und dem kann man erstmal ausgehen.
Es gibt ja noch einen nichtalgebraischen Teil der Optimierung, da
kommen wir auch das nächste Mal dann dazu.
Da werden dann Zugriffsfahrt und solche Dinge noch mit einbezogen.
Und da kommt es natürlich sehr darauf an, dass man viel weiß über den
Benutzer.
Oder über die Benutzung der Daten, der typischen Benutzung der
Datenbank.
Aber dieser algebraische Teil, da können Sie einfach davon ausgehen,
das ist Standard.
Okay, gut, das war also dieser B-Teil.
Achso, ja, insofern, dieses intuitive Modell hier, das ist natürlich
deshalb auch noch ganz interessant, weil man dann sich vorstellen
kann, wie der Optimierer dann arbeitet und was der da für ein
Potential hat und für Möglichkeiten hat.
Und das wäre dann etwas, das kommt dann im letzten Übungsblatt, da
werden wir auch mal so eine Anfragerelation, algebraische
Anfrageoptimierung durchführen.
So, jetzt kommen wir zum anderen Punkt, nämlich zu der Konsistenz und
der Möglichkeit, entsprechende Konsistenzbedingungen mittels SQL zu
formulieren.
Und da geht es jetzt darum, dass man eben gerade hier eine spezielle
Form von Konsistenzbedingungen formuliert, nämlich die der
referenziellen Integrität, also diese Fremdschlüsselbedingungen
sozusagen.
Und diese Fremdschlüsselbedingungen, die sind ja genau dann zu
erkennen, wenn man das entsprechende Schema anschaut und sieht, wo der
Schlüssel der Relation, zum Beispiel die Patientennummer, die Nummer
des Patienten, wo die in einer anderen Relation, zum Beispiel in der
Relation leidet, an, als Fremdschlüssel auftaucht.
Und genau darum ging es, dass man mal schaut, was sind denn da
überhaupt für Fremdschlüsselbeziehungen drin.
Und die habe ich nicht vorgegeben, die musste man so ein bisschen
erraten, wobei es war ja vorgegeben, was die Schlüssel sind und die
Benennung war so intuitiv gewählt, sodass man da eigentlich drauf
kommen könnte, was da entsprechende referenzielle
Integritätsbedingungen sind.
Und das muss aber angegeben werden dem System.
Also man kann da nicht davon ausgehen, dass diese intuitive Benennung
das ersetzt.
Das muss man explizit angeben und das kann man eben auch im Schema
machen.
Für Sie war jetzt die Frage, dass Sie da mal durchgucken und schauen,
wo könnte denn da was sein.
Wo müsste ich denn dann bei der Definition des Schemas eine Bedingung
dem Datenbanksystem nennen und bei der Schema-Definition vereinbaren.
Okay, da kann man durchgehen und dann sieht man relativ schnell, was
da alles möglich ist.
Also hier habe ich es mal aufgeschrieben, leitet an in so eine
Beziehung, stellt eine Beziehung dar zwischen Patient und,
beziehungsweise in dem Fall keine Beziehung, sondern sagt, dass ein
Patient, der in der Patienten-Relation drin enthalten ist, an einer
bestimmten Krankheit leidet, an einer oder mehreren.
So, und da heißt die Bedingung dann, also hier bei leitet an Patient
-Nummer, also in dieser Relation hier, da dieses Attribut Patient
-Nummer, das ist ein Fremdschlüssel und die Bedingung heißt dann, die
da erfüllt sein muss, dass wenn ich diese Relation leitet an, also das
muss man sich so vorstellen, dass das tiefer gesetzt ist, ich mache
mal das Pi ein bisschen größer, also ich projiziere auf Patient
-Nummer, kriege also genau die Nummern raus von Patienten, die in
dieser leitet an-Relation enthalten sind.
Und wenn ich dann eine Patient-Nummer finde, dann muss die auch in der
Relation Patient als Nummer aufgetaucht sein.
Sprich, diese Patient-Nummer in leitet an ist Fremdschlüssel, muss
also hier schon enthalten sein als Schlüssel in der Relation Patient.
Und das könnte man, oder muss man dann entsprechend in der Schema
-Definition vereinbaren.
Und hier habe ich mal den Ausschnitt praktisch angegeben, der dann bei
der Relation...
Ja, das ist wohl falsch, das muss wohl leitet an heißen.
Bei Handelt wäre es auch richtig, aber ich habe ja gerade von leitet
angesprochen.
Also in der Relation leitet an müsste da beispielsweise dann hier bei
der Definition der Patient-Nummer dann entsprechend noch die Bedingung
kommen, diese referenzielle Integritätsbedingung oder
Konsistenzbedingung, dass Patient-Nummer Fremdschlüssel ist und eine
Referenz hat auf das Attribut Nummer in der Relation Patient.
Und das ist genau diese Konsistenzbedingung.
Muss ich aber definieren.
So, genau die gleichen Sachen gibt es dann hier eh.
Okay, die gibt es natürlich nicht, deswegen...
Sorry, das habe ich vereinfacht und habe das vergessen rauszunehmen.
Also es gab vorher noch eine Relation Krankheit, die habe ich einfach
rausgeschmissen und habe es hier vergessen auch zu entfernen.
Okay, das mache ich dann noch raus auf dem Übungsblatt, auf den
Lösungen.
Dann beim Behandelt gibt es die Patient-Nummer.
Und da gilt dasselbe wieder, dass diese Patient-Nummer natürlich auch
zu einem Patienten gehören muss.
Also als Nummer in der Relation Patient enthalten sein muss.
Und bei Behandelt Arzt-Nummer ebenfalls, dass nämlich der Arzt, der
durch diese Nummer identifiziert wird, der in Behandelt vorkommt, dass
der auch in Arzt enthalten sein muss.
Okay, also referenzielle Integrität, Fremdschlüsselbedingungen.
So, hier kommen wir jetzt einen Schritt weiter.
Was können wir denn noch anbieten?
Und wenn wir so mit dem Datenbanksystem arbeiten und darauf achten,
wie da...
Wir haben ja in der Regel eine Datenbasis ist dazu da, dass man da mit
sehr vielen verschiedenen Anwendungen, mit vielen verschiedenen
Benutzern auf die Daten zugreift.
Das ist ja immer mehr Benutzerbetrieb eigentlich das, was so das
typische ist, wenn es sich lohnt, ein Datenbanksystem mit den
entsprechenden Mechanismen, Transaktionsverwaltung usw.
einzusetzen.
So, und da kriegt sofort das Problem auf, dass man natürlich
normalerweise unterschiedliche Benutzergruppen hat, die
unterschiedliche Rollen auch einnehmen und nur bestimmte
Zugriffsberechtigungen haben auf die Daten.
Man möchte nicht allen die gleichen Daten zeigen.
Manchen nur einen Ausschnitt, manche dürfen nur lesen, manche dürfen
auch schreiben usw.
So, das ist eigentlich eine ganz normale Sache, wenn man mit großen
Datenbeständen arbeitet und mit so großen Datenbasen arbeitet, die von
mehreren unterschiedlichen Nutzergruppen genutzt werden sollen.
Und hier haben wir jetzt eine Aufgabe, dass wir hier so empfindliche
Daten haben über Personen.
Und jetzt war die Frage, dass man die Aufgabe hat, den Zugriff für die
Statistikabteilung so einzuschränken, dass nur Daten über
diagnostizierte Krankheiten lesbar sein sollen und die zugehörigen
Behandlungen.
Gut, dann noch über Krankheiten allgemein, das müssten wir dann noch
einführen, wenn man das haben möchte.
Die sind dann noch sichtbar.
Aber was gesperrt sein soll, ist insbesondere die personenbezogenen
Daten zu Patienten, nämlich das, was über den Patienten gespeichert
ist und welcher Patient das ist und zu Ärzten, insbesondere zum
Beispiel auch, welcher Patient von welchem Arzt behandelt wird.
Und die Frage war jetzt, wie man da was erreichen kann, dass diese
Statistikabteilung mit diesem speziellen Profil und vor allem mit
diesen eingeschränkten Rechten, wie man die trotzdem auf die
Datenbasis loslassen kann.
Und hier greift die Möglichkeit, dass man Sichten definiert.
Und dann entsprechend aber noch zusätzlich über diesen Sichten nicht
nur den Zugriff ermöglicht, sondern auch die anderen
Zugriffsmöglichkeiten über die Basisrelation beispielsweise für diese
Statistikabteilung nicht freigibt.
Also es muss auch noch gegeben sein, dass man da auch noch die
Zugriffsrechte entsprechend einschränkt.
Es reicht also nicht nur die Sichtendefinition, sondern ich muss dann
auch die Zugriffsrechte noch entsprechend setzen.
Darf man also nicht vergessen.
Okay, wir haben also hier einmal die Zugriffsrechtegewährung, das wäre
der Grantbefehl.
Und wir haben die Sichtendefinition.
Und diese zwei werden dann benutzt, um solche speziellen
Zugriffsmöglichkeiten für bestimmte Rollen, für bestimmte
Benutzergruppen auch einzurichten.
So, dann müsste man beispielsweise hier eine Sicht einführen, die
jetzt nur die Informationen enthält, die wir haben wollen.
Wir hatten ja vorher in den Relationen dann entsprechend die Krankheit
drin.
Und die Relation leitet an, da war ja die Patientnummer und der
Krankheitsname drin vermerkt.
Krankheitsname interessiert uns durchaus, aber die Patientnummer soll
nicht veröffentlicht werden.
Also das war so ein Problem.
Weil über die Patientnummer könnte man gegebenenfalls irgendwie
Rückschlüsse ziehen, wer diese Person ist.
Das heißt, zwischen diesem leitet an und der Krankheit, da kann man
entsprechend beispielsweise so eine Sicht definieren.
Statistik leitet an.
Und da steht dann beispielsweise drin, Anzahl Personen und
Krankheitsname.
So, Anzahl Personen, das ist neu.
Neues Attribut.
Krankheitsname, das kennen wir schon aus dem leitet an.
Und wenn wir uns jetzt das leitet an, gerade vielleicht unten drunter,
schreibe ich das mal kurz hin nochmal.
Leitet an, da war also praktisch drin die Patientnummer.
Und der Krankheitname.
Und das ist jetzt ein Beispiel hier draußen.
Wenn ich jetzt eben sowas jetzt rauskriegen möchte, dass ich so eine
Sicht mir definiere, müsste ich hier praktisch eine Selektanweisung
definieren, indem ich hier nicht die Patientnummer rausgebe, sondern
hier die Anzahl der Personen, die an einer bestimmten Krankheit
leidet.
Und wie mache ich das dann an der Stelle?
Ich habe das hier gar nicht ausgeführt, aber ich denke, das ist etwas,
was man dann sehr schön als Übung für SQL verwenden kann.
Ich müsste hier praktisch eine Aggregierungsoperation verwenden, indem
ich nämlich einen Count mache, über die Anzahl, über die Personen,
Patientennummern.
Und vorher muss ich aber, da ich die Anzahl der Personen möchte, die
an einer bestimmten Krankheit leiden, müsste ich noch eine Gruppierung
machen nach dem Krankheitsnamen und könnte dann nur in diesen Gruppen
noch entsprechend die Patienten zählen, die da drin sind.
Also müsste ich hier sowas in der Richtung wie Count, Patientnummer
und Krankheitname.
Ich skizziere es nur ganz kurz.
Hier kommt nur die Relation vom Leidet an.
Und dann kommt hier noch eine Gruppierung, muss ich noch definieren.
Und zwar möchte ich ja nach Krankheitname gruppieren.
Ja.
Nee, aber ich kann auf blau wechseln.
Danke, das ist nämlich klasse.
Ich sehe das bei mir wunderbar, nur auf der großen Leinwand über dem
Beamer ist das total anders.
Also das Grün ist wunderbar zu sehen bei mir.
Leidet an.
Sorry.
Und Krankheitname.
So, jetzt haben wir es.
Also sowas wäre dann möglich, dass man so eine Sicht definiert.
Und dann müsste man aber im Nachhinein noch als zusätzliche Maßnahme
noch über die Zugriffsrechtevergabe das so steuern, dass diese Gruppe,
diese Statistikabteilung hier, dass die dann auch darauf eben lesende
Zugriffsrechte hat.
Also schreibende macht sowieso keinen Sinn, weil wir hier ja eine
Account -Operation haben, also eine Aggregierungs-Operation und da
kann man schlecht was ändern.
Also das Grant ist sehr wichtig an der Stelle und ich muss natürlich
dann gewährleisten, dass diese Statistikabteilung nicht noch auf die
Leidet an-Relation beispielsweise Zugriffsrechte hat, vollständige.
Das muss gewährleistet sein.
In der Regel läuft es so ab, dass man, also wenn man eine gezielte
Zugriffsrechtevergabe macht, was bei größeren Datenbanken unter
Benutzung von verschiedenen Rollen und Gruppen durchaus wichtig ist,
dann geht man davon aus, dass man einstellt, das kann man beim
Datenbanksystem einstellen, dass man sagt, es ist nur erlaubt, was
explizit auch erlaubt wird über einen Grantbefehl.
Wenn man also nichts erlaubt, dann ist erstmal alles verboten, bis auf
den Administrator.
Das heißt, man muss da an der Stelle einiges an Aufwand treiben, um
die Zugriffsrechtevergabe zu betreiben, hat aber dann auch die
Sicherheit, dass man nicht was vergessen hat, einzuschränken.
Also im anderen Fall, wenn ich nichts angebe und es würde dann
angenommen werden, alles ist dann erlaubt, wenn ich keine
Zugriffsrechte vergib, dann hätte man halt das Problem, dass ich
irgendwas übersehen könnte.
Also das ist schon besser, wenn man von der Seite her kommt, erstmal
ist alles verboten und nur das, was ich explizit erlaube, ist auch
zulässig dann.
So, das war ein kleiner Ausflug in die Schutzproblematik.
Hier kommt noch eine kleine Frage zu der, wo man sich einfach nochmal
überlegen sollte, was gibt es denn da für Einschränkungen für Sichten.
Da hat Herr Lockermann das ja sehr drastisch dargestellt und gesagt,
also da gibt es halt enorme Einschränkungen, man kann nur Änderungen
in Sichten zulassen, wenn die Sichten so definiert sind, dass sie ganz
bestimmten Bedingungen genügen, zum Beispiel keine
Aggregierungsoperationen dürfen enthalten sein und die
Basisrelationen, die dann vorhanden sind, müssen halt entsprechend
alle Attribute nach oben liefern oder die wichtigen Attribute, also es
gab da ja so einen Satz an Regeln, wann auf jeden Fall, im allgemeinen
Fall, Sichtenänderungen möglich sind.
Häufig ist es aber so, dass in der Praxis da solche Sichten auch, also
die können auf zweierlei Art und Weise eingesetzt werden.
Häufig ist es so, dass zum Beispiel solche Statistikabteilungen
zufriedengestellt werden müssen, für so kritische Daten.
Und da kann man sehr gut eine Sicht definieren, weil die nämlich
eigentlich nur das Lesen zugreifen wollen.
Das ist ein typischer Fall.
Und der andere Fall, den man hat, wenn man Sichten einsetzen möchte,
der hat dann noch ein bisschen ein anderes Bewandtes, dass man nämlich
vielleicht eine andere Kombination der Attribute oder eine Umbenennung
der Attribute haben möchte.
Oder eventuell auch, was bei manchen moderneren
Sichtendefinitionsmöglichkeiten gegeben ist, dass man so eine gewisse
Umstrukturierung halt erlaubt.
Aber eigentlich die Information alle da ist.
Und darüber kann man natürlich dann auch Änderungen machen.
Also es ist in der Praxis schon so, dass man mit Sichten als Konzept
durchaus einiges anrichten kann.
Dass man durchaus einiges erreichen kann, nicht anrichten kann,
erreichen kann.
Und das auch ein sehr positives Konzept ist, auch wenn es erst mal so
klang, als ob man das eigentlich nie einsetzen könnte.
Also man muss auch sehen, wo es eigentlich genutzt wird.
Wenn ich dran denke, wir werden auch noch... nee, das wird nicht mehr
kommen.
Aber es gibt in weiterführenden Veranstaltungen wird zum Beispiel auch
darauf eingegangen, dass man dann so objektorientierte Sichten auf
Relationen erstellt.
Das ist auch eine Sichtenbildung.
Und da geht es darum, dass man eigentlich mehr so objektorientiert
arbeiten möchte, weil man von einer objektorientierten Sprache kommt
und dann aber eine relationale Datenbasis nutzt, die da zugrunde
liegt.
Und da sieht man sehr gut, da strukturiert man einfach um und hat eine
andere Sicht darauf.
Und da wird es auch sehr häufig eingesetzt.
Also da gibt es auch entsprechende Werkzeuge, die das unterstützen,
solche Sichten zu erstellen.
Gut, aber jetzt hier, Sichten war also an der Stelle eine Sache.
Dann habe ich hier noch etwas ausgeführt, das möchte ich jetzt
eigentlich nicht beschreiben.
Das kann man sich durchlesen, ich habe es sehr ausführlich gemacht.
Da geht es jetzt gerade darum, wie man jetzt dieses Problem, das in e
hier dargestellt ist, diese Sichten, wenn man eventuell doch schreiben
zulassen möchte, Änderungen zulassen möchte, an dieser Stelle und doch
sehr restriktiv ist mit den Daten, die man nach außen gibt, wo man da
an Grenzen stößt und was man machen müsste.
Und was halt dann einfach auch nicht machbar ist.
Das habe ich ein bisschen ausgeführt, kann man sich mal anschauen.
Jetzt gehen wir zur zweiten Aufgabe und gehen mal an die Übung ran,
dass wir SQL nutzen, um Anfragen zu stellen.
Ich habe auf dem Übungsblatt immer auch nur natürlich einen
Lösungsvorschlag, es gibt da sehr viele verschiedene.
Das hängt davon ab, wie man gerne rangeht und wie man denkt, wenn man
so eine SQL-Anfrage formuliert.
Wenn man sich überlegt, welche Elemente enthalten sind und wie die
miteinander verknüpft sind.
Also deswegen, das ist nur ein Vorschlag, es gibt sicher eine ganze
Reihe anderer richtiger Lösungen.
Wenn Sie da irgendwie Fragen haben, können Sie auch gerne nochmal im
Nachhinein bei mir vorbeikommen oder auch mal eine E-Mail schicken
oder sowas.
Das ist also kein Problem.
So, hier also mal eine Aufgabe.
Wir haben hier zwei ganz einfache Relationen.
Land und Stadt.
Und interessanterweise haben diese Relationen die gleichen Attribute.
Allerdings mit einer anderen Bedeutung, zum Teil.
Land hat das Attribut Name, das ist wohl der Name des Landes.
Stadt hat das Attribut Name, das soll der Name der Stadt sein an der
Stelle, sinnvollerweise.
Einwohner, wenn ich hier Einwohner schreibe, dann sind es wohl die
Einwohner der Stadt, die ich hier haben möchte.
Bei den Einwohnern hier handelt es sich um die Einwohner, die dieses
Land hat.
Also eine ganz andere Semantik.
Und beim Land-ID, das ist ein bisschen anders noch.
Hier haben wir bei Land einen Land-ID und das ist ein eindeutiger
künstlicher Schlüssel, den ich hier einführe.
Und auf dem Übungsblatt habe ich auch hier das als Schlüssel
identifiziert.
Und da sieht es jetzt so aus, dass ich praktisch hier einfach nochmal
dieses Land-ID zur Identifikation des Landes habe.
Hier unten bei der Stadt habe ich diesen Land-ID, um darzustellen,
dass diese Stadt in diesem Land mit diesem Land-ID liegt.
Also das wäre jetzt der Fremdschlüssel und würde praktisch sagen,
diese Stadt mit diesem Namen, die liegt in diesem Land mit diesem Land
-ID.
Und da es Städte gibt, die mit dem gleichen Namen in unterschiedlichen
Ländern, muss ich hier als Schlüssel, was auch auf dem Übungsblatt
angegeben ist, das hier als Schlüssel wählen.
Also Berlin gibt es nicht nur in Deutschland, gibt es auch in den USA,
gibt es auch sonst wo.
Okay, das waren die Relationen.
Das nächste ist, wir haben hier noch so eine zusätzliche Aussage, die
im Hintergrund halt bekannt sein muss, um nachher die Anfragen zu
formulieren.
Ich könnte es auch in die Anfragen reinschreiben, aber eigentlich ist
das etwas, was man über den Inhalt der Datenbasis wissen muss, um
damit zu arbeiten.
Ein Land, in dem mehr als 10% der Bevölkerung dieses Landes in
Großstädten lebt, gilt als stark urbanisiert.
Als Großstädte, die haben wir ja noch nicht definiert, werden Städte
mit mehr als 500.000 Einwohnern betrachtet.
Kann man sich also gut vorstellen.
Großstädte sind die Städte, wo hier die Einwohnerzahl mehr als 500.000
beträgt.
Das Land, da wird es ein bisschen komplizierter, aber das werden wir
ja auch gleich machen.
Da geht es darum, dass man hier wissen möchte, wie viele der
Einwohnerleben dieses Landes, wie viele von dieser Gesamteinwohnerzahl
dieses Landes leben in diesem Land natürlich, leben in Großstädten.
So, jetzt gehen wir mal ganz vorsichtig ran, nennen Sie alle in der
Datenbasis erfassten Städte in Spanien.
Das dürfte eigentlich noch recht einfach sein.
Also, ich könnte natürlich sagen Stadt, ich möchte die Städte haben.
Entschuldigung.
Die Städte haben und ja, das LandID muss der von Spanien sein.
Da ich den aber nicht kenne, das ist ja so ein künstlicher Schlüssel,
den man irgendwie halt zur Vereinfachung nutzt, muss ich wohl oder
übel an die Relation Land noch mit ran und da schauen, was der Name
ist.
Und da schauen, was der LandID des Landes mit Namen gleich Spanien
ist.
Das ist hier dieser Fremdschlüssel.
Macht es uns hier notwendig, wenn ich hier direkt den Namen des Landes
eingetragen hätte als Fremdschlüssel, hätte ich das jetzt nicht
notwendig.
Aber wir haben ja hier so einen künstlichen Schlüssel eingeführt.
Gut, schauen wir uns mal an, wie das aussieht.
Select Stadt.Name from Land und Stadt, wer Land.LandID gleich Stadt
.LandID and Land.Name gleich Spanien.
Also, wie gesagt, das hier brauchen wir ja, um die Länder auszusuchen.
Wir brauchen Land und Stadt, weil wir ja an den Namen der Städte
interessiert sind.
In der From-Klausel.
Und dann müssen wir noch die Beziehung herstellen zwischen den Ländern
und den Städten, weil wir ja nur die Städte haben wollen, die in
diesem Land liegen.
Und deswegen müssen wir hier diese Gleichheitsbedingungen noch
einfügen.
So, gehen wir weiter.
Jetzt geht es los.
Ah, noch nicht.
Ermitteln Sie die Anzahl der Einwohner der Länder, die mindestens eine
Stadt mit Anfangsbuchstaben Y haben.
Da kommt es jetzt einfach, das ist auch noch relativ einfach, Anzahl
der Einwohner der Länder, die mindestens eine Stadt mit
Anfangsbuchstaben Y haben.
Ja, die Einwohner der Länder, die steht ja in der Relation Land drin.
Aber ich brauche jetzt auch wieder die Relation Stadt dazu, weil ich
nämlich eine Bedingung habe über den Namen der Stadt.
Die soll nämlich vom Text her, vom String, das ist eine String
-Definition, die muss mit Y anfangen.
Das kann ich in SQL formulieren, mit diesem like Konstrukt.
Aber hier sehe ich, ich möchte zwar als Ergebnis nur die Einwohner der
Länder haben, aber ich brauche trotzdem die Relation Stadt, um die
Anfrage zu bearbeiten, weil ich eine Bedingung habe über die Namen der
Städte.
Gucken wir uns auch gleich an.
Ich habe es jetzt hier so formuliert, weil eigentlich...
Das stimmt eigentlich nicht, oder?
Ich bin gerade am Überlegen.
Die Anzahl der Einwohner der Länder, die mindestens eine Stadt mit
Anfangsbuchstaben Y haben.
Okay, also ich meine, falsch ist es nicht, aber es ist eigentlich
überflüssig, was ich da angegeben habe.
Gucken wir gleich nochmal, vielleicht sieht es ja gleich jemand.
Also ich wollte jetzt hier ausdrücken, das erste ist mit dieser
Anfrage, die sicher richtig ist, aber vielleicht etwas zu viel enthält
an Aufwand.
Wir möchten den Namen haben, der Länder, weil das eigentlich schon
wichtig ist, dass wir gerne wissen wollen, was für Länder sind denn
das.
Und dann wollen wir noch gerne die Einwohner haben, dieses Landes.
Ja, das ist falsch sogar.
Also ich muss diese Einwohner, die Summe hier, muss ich wohl
wegstreichen.
Hat jemand die Aufgabe gemacht und kam zu dem anderen Ergebnis?
Ja, nur will ich halt eigentlich nicht die Einwohner, die in den
Städten leben, sondern die Einwohner der Länder.
Ja, aber das ist nicht gefragt.
Ich glaube, das wollte ich dann irgendwie reinbringen.
Also das ist falsch hier an der Stelle, das Summen.
Eigentlich reicht es mir, wenn ich hier das Summen wegstreiche oder
ich muss es sogar tun.
Machen wir es mal so als Ergebnis.
Ich schreibe da noch was dazu, was diese Summe...
Das ist eigentlich Unsinn an der Stelle, das ist einfach zu viel.
Also hier steht nirgends was, dass ich die Einwohner der Städte haben
möchte.
Das wäre ja, dann müsste man summieren, ja.
Aber das steht nirgends, sondern ich möchte einfach die Einwohner der
Länder haben.
Und zwar an der Stelle hier jetzt...
Okay, ich kann es auch wieder...
Es ist halt hier natürlich sprachlich.
Machen wir es jetzt mal so, ich sage dann noch eine andere Lösung, wo
das Summen durchaus eine Bewandtnis hätte.
Also hier wollen wir jetzt die Einwohner und die Namen von Ländern
haben.
Vom Land.
Und das ist das, was ich brauche am Schluss.
Das ist das, was ich haben möchte.
Und deswegen habe ich hier praktisch auch nur das Land als Relation
angegeben.
Und habe in der Where-Bedingung dann eine geschachtelte Anfrage drin
und eine Existenzbedingung drin, die mir dann nämlich die Länder hilft
auszusuchen.
Weil die brauche ich ja, die Information der Länder brauche ich
nachher nicht hier oben in der Select-Anweisung.
Ich hätte es auch anders formulieren können.
Ohne dieses Exist.
Ja, obwohl das an der Stelle wird es kritisch.
Aber hätte man machen können.
Also man kann es so machen, wer exist und dann wähle ich hier aus die
Städte und davon den Namen beispielsweise.
Und der Name, der soll halt mit Y beginnen.
Und diese Stadt, die soll in dem Land liegen.
Das ist jetzt wichtig.
Dass ich hier diese innere Select-Anweisung verknüpfe mit dem Tuppel
von außen, mit den Ländern, die ich außen dann auswähle und von denen
ich dann den Namen und die Einwohner rausgebe.
Die muss ich ja irgendwie verknüpfen miteinander.
Und diese Verknüpfung, die erfolgt genau hier.
Hier drin sieht man, da nutze ich nur Stadt.
Hier in der äußeren Schleife habe ich Land.
Und diese Bedingung hier, die formuliere ich über einem Attribut der
Relation, die hier in der Select-Anweisung nur Verwendung findet.
Und mit einem Attribut, das in der umgebenden Select-Anweisung
definiert ist.
Und hier mache ich praktisch die Verknüpfung dann.
Dass ich nur die Städte von dem Land dann habe.
Die Abarbeitung erfolgt dann so.
Ich würde dann hier, das kathesische Produkt ist hier einfach, das ist
nämlich genau die Relation Land.
Würde ich rauskriegen.
Ich würde dann anschließend eine Selektionsbedingung machen müssen.
Indem ich hier nämlich suche nach den Ländern.
Also ich gehe hier praktisch tuppelweise durch.
Nimm das erste Land aus der Relation Land.
Und schaue danach, existiert in diesem Land, das ich jetzt gerade
angucke.
Existiert da eine Stadt, die mit Y anfängt?
Wenn ja, dann kommt dieses erste Land-Tuppel in die Ergebnismenge
rein.
Und dann würde ich noch die Schlussprojektion ausführen.
Würde ich nämlich die Einwohner und den Namen ausgeben von diesem
Land.
Dann würde ich hier das zweite Tuppel von Land.
Also hier würden praktisch die Land-Tuppel, schreibe ich mal einfach
hin, abarbeiten.
Würde ich das zweite Tuppel von Land nehmen.
Schauen, für diesen Land-ID gibt es da mindestens eine Stadt, die mit
Y anfängt.
Wenn ja, würde die auch wieder ins Ergebnis übergeführt werden.
Und Einwohner und Namen herausprojiziert werden.
Wenn nein, entfällt sie.
Und dann gehen wir zum nächsten Tuppel und so weiter.
So läuft das Ganze als absolutes Abgearbeitet.
Ich könnte mir auch vorstellen, dass ich die Anzahl der Einwohner, die
Gesamtsumme der Einwohner der Länder haben wollte.
Das müsste ich aber dann hinschreiben.
Also ich würde das nicht unbedingt hier so formulieren.
Dann könnte ich beispielsweise sagen, dann wäre es in Ordnung, dann
hätte ich Select zum Einwohner.
Und dann kommt das von oben.
Also Gesamtsumme aller Länder, die mindestens eine Stadt mit
Anfangsbuchstaben Y haben.
So könnte ich sowas dann einführen.
Und dann wäre das in Ordnung.
Also das ist dann ein bisschen blöd hier, weil ich das mit Namen
verknüpft habe.
Und hier kriege ich ja die Gesamtsumme raus.
Dann hätte ich da den Namen und würde immer die gleiche Gesamtsumme
bekommen.
Ja, ich könnte hier auch Stern schreiben.
Das ist egal.
Das ist richtig, ja.
Nein, denn dann käme ja nichts raus.
Dann wäre das Ergebnis eine leere Menge, wenn ich nichts
rausprojiziere am Schluss.
Die Projektion auf eine leere Menge sozusagen.
Auf keine Attribute liefert mir nichts in dem Fall.
Und das wäre dann leer.
Also ich könnte hier Stern angeben.
Wäre durchaus genauso richtig.
Sogar intuitiver.
Ja, also ist beides richtig.
Gut.
So, und jetzt kommen wir zu den Großstädten.
Also, welche Länder haben mehr als 10 Großstädte?
Geben Sie auch an, wie viele Großstädte dies jeweils sind.
Jetzt wird es schon ein bisschen haariger.
Ich schiebe es mal hier rauf.
Ausgleich als Ergebnis.
Dann besprechen wir die entsprechende Select-Anweisung.
So, jetzt gehen wir mal einfach so vor, dass wir uns überlegen, welche
Länder haben mehr als 10 Großstädte.
Wir brauchen erstmal Länder und Städte mal wieder.
Insofern ist das ja schon mal okay.
Und was wollen wir rauskriegen?
Wir wollen die Namen der Länder haben.
Und dann wollen wir wissen, wie viele Städte dies sind.
Count, Stadt, Punkt, Name.
Aber nur die Städte, die in dem einen Land sind.
Also die müssen gruppiert sein nach Land.
Ich möchte hier das Land angeben und dann wissen, wie viele Städte in
diesem Land sind jetzt Großstädte.
Also pro Land muss ich also gruppieren nach Land.
Genau das mache ich hier unten.
Ich gruppiere hier nach Land.
Ich sage gleich noch was, warum hier zwei Attribute sind.
Aber erstmal das Grundsätzliche.
Also ich gruppiere nach Land und anschließend möchte ich hier dann
zählen in der Gruppe, wie viele Städte sind denn da noch drin.
Und das mache ich dann über Count, Stadt, Punkt, Name.
Innerhalb des Landes ist ja der Städtename eindeutig.
Schlüssel war ja Land-ID und Stadt-Name.
Also deswegen ist das zusammen Schlüssel.
Deswegen kann ich die hier zählen und kriege dann raus, wie viele
Städte sind dann in dem Land drin.
Jetzt weiß ich erstmal nur die Städte.
Genau, das muss ich machen.
Da ist irgendwas schief gelaufen.
Gut, auch recht.
Irgendwie habe ich da eine falsche Version erwischt.
Eine zerstümmelte Version.
Also gut, dann müssen wir das jetzt hier machen.
Das ist natürlich Blödsinn.
Count, da fehlt vor allem...
Also das stimmt überhaupt nicht an der Stelle.
Gut, schauen wir uns gerade nochmal an, wie groß Städte definiert
sind.
Dann schreiben wir es jetzt nochmal hin.
Gut, kein Problem.
Ja, ich muss ja auch noch abprüfen, dass es mehr als 10 Städte sind.
Und jetzt muss ich aber noch die Städte raus...
Genau, das fehlt.
Also hier habe ich jetzt, das wäre praktisch das Ergebnis ohne das
Groß.
Also, welche Länder haben mehr als 10 Städte?
Das wäre diese Anfrage hier.
So, jetzt gehen wir zu den Großstädten über.
Und jetzt müssen wir in der Tat noch einfügen.
Die Abprüfung, dass wir jetzt nämlich nur die Städte betrachten, die
auch Großstädte sind.
Und da müssen wir jetzt noch eine Einschränkung machen.
Und das kann ich hier oben in der Verklausel machen.
Das heißt, ich müsste jetzt hier an der Stelle...
eine Bedingung einfügen, jetzt welche.
Jetzt sage ich nur nochmal, wie das definiert ist.
Als Großstädte werden Städte mit mehr als 500.000 Einwohnern
betrachtet.
Okay, da haben wir unsere Bedingung.
Die können wir jetzt sehr schön hier einfügen.
Und sehr schön aufgepasst war das eben, dass man nämlich jetzt hier
noch sagt...
Stadt und Stadtpunkt Einwohner...
größer als 500.000.
So, wenn ich das hier in der Verklausel angebe, dann werden die
Städte, die ich im darauffolgenden, also vor der Gruppierung...
wird es ja bearbeitet, diese Verklausel hier.
Also nur noch die Städte sind dann noch da, die Großstädte sind.
Und dann gruppiere ich erst.
Also, ich gehe hier so vor.
Ich schaue mir Land und Stadt an, kombiniere die miteinander.
Hier sehe ich, da ist ja gleich noch eine Verknüpfung da.
Das heißt, ich bilde mir Tuppel.
Ich bilde mir nicht das kathesische Produkt insgesamt, sondern
schränke gleich noch ein.
Dass ich nämlich dann nur die Städte, die Tuppel übernehme aus dem
kathesischen Produkt, wo der Land-ID der Stadt gleich dem Land-ID des
Landes ist.
Das heißt, ich kombiniere immer nur die Land-Attribute mit den Stadt
-Attributen für die Städte, die in diesem Land liegen.
Genau das möchte ich ja gerne haben.
Also Land plus Stadt, die da drin liegt, ist ein Tuppel.
Zweites Tuppel wieder Land plus vielleicht eine andere Stadt, die da
drin liegt.
Und dann noch ein anderes Land und da die Stadt, die da drin liegt und
so weiter.
So, das kriege ich hier raus in den Ware-Teil.
Also Form und Ware werden dann abgearbeitet.
Und dann komme ich praktisch...
Also das wäre hier erster Abarbeitungsschritt.
Zweiter Schritt würde diese Joint-Operation machen.
Und dann hätte ich diese Select-Anweisung, die ich hier mache.
Also praktisch die Select-Operation, wenn ich in relationaler Algebra
denke.
Ich schränke jetzt ein auf die Städte, die Großstädte sind.
Und im nächsten Schritt gehe ich jetzt an die Gruppierung.
Jetzt kommt Gruppierung.
Und jetzt gruppiere ich nach Ländern.
Kriege dann also das Land Deutschland und die Großstädte Berlin,
Frankfurt und so weiter.
Und dann habe ich hier die Gruppen.
Und dann kommt die USA mit, New York und so weiter.
Und dann kommt als nächstes, als fünfter Schritt praktisch, dass ich
hier jetzt auf diesen Gruppen noch eine Bedingung formuliere.
Ich wähle mir jetzt nämlich nur noch die Gruppen aus, für die diese
Bedingung hier gilt.
Das Having bezieht sich also jetzt auf die Auswahl der Gruppen.
Also schaue ich mir dann an, die Gruppen, zum Beispiel schaue ich mir
in Deutschland an, wie viele Städte sind denn in dieser Gruppe drin
enthalten.
Fähle die und wenn die Zahl größer gleich 10 ist, dann kommt diese
Gruppe Deutschland ins Ergebnis rein.
Wenn nicht, dann entfällt das.
Dann kommt es nicht ins Ergebnis rein, dann ist diese Gruppe draußen.
Und dann, wenn wir das gemacht haben, kommt als nächster Schritt
sozusagen die Auswertung
der Select-Klausel oben, dass ich sage, welche Attribute interessieren
mich jetzt.
Und da interessiert mich halt der Name des Landes.
Und dann, was ich auch noch machen kann, ich kann jetzt, das wird
jetzt über die Gruppe gemacht, ich kann jetzt dort die Städte zählen,
die da in der Gruppe enthalten sind.
Und kriege das dann auch pro Land die Anzahl der Städte, die in dieser
Gruppe des Landes enthalten sind, raus.
Wegen dem Land-ID hier unten, oder was?
Ja, also ich habe es deshalb angegeben, weil Land.Name wird man
natürlich...
Also ich könnte hier ja kopieren nach Land-ID, das wäre das
Natürliche, weil das der Schlüssel ist.
Dann kriege ich eindeutige Gruppen für jedes Land.
Genau, und das ist der Punkt, wenn ich hier gruppiere, dann kann ich
ja dann anschließend nur auf dieses Attribut zugreifen, das ich bei
der Gruppierung auch benenne, oder auf die Attribute, die ich dort
benenne.
Ich kann hier oben nicht beliebige Attribute dann hier verwenden im
Ergebnis, weil ich erstelle mir ja jetzt erstmal Gruppen und dann
kriege ich ja einen Tuppel raus für jede Gruppe.
Und da steht hier drin, was ich für diese Gruppe bekomme.
Für diese Gruppe kann ich hier eindeutig einen Land-ID bekommen.
Wenn ich den Namen jetzt weglassen würde, könnte ich den nicht
zugreifen, weil da könnte es ja vielleicht mehrere geben.
Das ist jetzt bei uns nicht der Fall, das wissen wir, aber es könnte
im Prinzip mehrere geben.
Ich wollte ja eigentlich pro Land die Anzahl der Städte haben und wenn
der Name hier nicht vorhanden ist, dann kann das System natürlich auch
nicht für diese eine Gruppe jetzt einen Namen auswählen.
Es könnte ja mehrere geben, pro Land-ID.
Das Problem ist, ich gebe hier oben, arbeite ich dann nur noch auf der
Gruppe.
Ab hier, ab Schritt 4, bin ich bei den Gruppen.
Und dann kann ich oben, beim Schritt 6, das basiert ja dann nur auf
den Gruppen noch, da kann ich nur das noch ausgeben, was in der Gruppe
bekannt ist.
Deswegen muss ich hier Land.Name noch angeben.
Ich könnte an der Stelle auch Land-ID weglassen, weil wir wissen, dass
der Name des Landes eindeutig ist.
Aber ich habe es einfach mal der Vollständigkeit halber, weil es
Schlüssel ist, habe ich das mit eingeführt.
Es ist nicht unbedingt notwendig, ich mache das mal mit Rot.
Ich mache es mal mit Grün, das sieht man nicht so arg.
Weil es eigentlich möglich ist, man kann es so lassen.
Ohne... auch in Ordnung.
Also ich möchte es nicht so in Rot machen, weil es eigentlich nicht
falsch ist.
Aber man könnte es auch weglassen.
So, und damit kriegen wir dann raus, wenn wir das hier noch eingefügt
haben, welche Länder mehr als 10 Großstädte haben.
Also wichtig ist, dass man sich immer überlegt, wie man vorgeht, wie
das Ganze abgearbeitet wird und wann die Gruppierung greift.
Und dass man diese Having-Klausel dann auf diesen Gruppen, auf den
Einzelgruppen durchführt.
Das sind die Bedingungen auf den Einzelgruppen.
In der Where-Klausel, wie man es hier sieht, das sind Bedingungen
erstmal auf diesem kathesischen Produkt hier, das vor der Gruppierung
erstellt wird.
So, jetzt gehen wir mal weiter.
Noch eine Frage, ja?
Ich habe es akustisch nicht verstanden, deswegen...
Unterschied zwischen was?
Zwischen Gruppe und Gruppei?
Oh, das heißt Gruppei.
Da gibt es keinen Unterschied, das ist ja unvollständig.
Gruppei, danke.
Gruppei muss es heißen, ja.
So, und jetzt kommen wir zu den stark urbanisierten Ländern und da
ging es ja jetzt darum, dass man jetzt wissen will, also jetzt kennen
wir ja schon ziemlich gut die Gruppierung und jetzt kann man sich
eigentlich überlegen, wie man da jetzt vorgeht, um so stark
urbanisierte Sachen rauszukriegen.
Und da ging es ja darum, stark urbanisiert hieß, ein Land, in dem mehr
als 10% der Bevölkerung in Großstädten lebt.
Und genau die gelten als urbanisiert und das mit den Großstädten hat
man ja schon geklärt.
Das war das mit den 500.000 Einwohnern und das kann man dann
entsprechend formulieren.
Und da kriegt man auch wieder so eine Gruppei, hier ist es richtig
jetzt mit dem Gruppei, Gruppei-Klausel rein.
Man hat vorher die Einschränkung auf die Großstädte.
Man hat hier die Verknüpfung, dass man nur die Städte eines gewissen
Landes miteinander in Beziehung setzt.
Also nicht beliebige Städte und Länder, sondern nur die Länder und
Städte als Tubel betrachtet.
Und dann macht man wieder eine Gruppierung.
In dem Fall über den Namen des Landes und die Einwohner des Landes.
Und zwar, weil wir nämlich die Einwohner des Landes nachher in dieser
Having -Klausel hier verwenden wollen.
Das ist hier noch speziell.
Hier verwenden wir Einwohner.
Und deswegen muss das in dieser Gruppei-Klausel enthalten sein.
Also ich gruppiere jetzt hier praktisch, ich erstelle eine Gruppe mit
Namen des Landes und Einwohnerzahl des Landes.
Die beiden Attribute kennzeichnen mir die Gruppe.
Im Prinzip könnten es dann auch das gleiche Land mit mehreren
Einwohnern, mehrere Gruppen geben, wenn da Unterschiede wären.
Aber wir wissen ja, ein Land hat eine bestimmte Anzahl von Einwohnern.
Insofern kriegen wir da pro Land genau eine Gruppe raus.
Und da sind aber noch die Einwohner enthalten.
Und dann mache ich noch eine Bedingung über diese Gruppe.
Und diese Bedingung sagt mir gerade, das wird ja in der Having-Klausel
angegeben, da ist ja die Bedingung über die Gruppen, die ich auf den
Gruppen, auf den einzelnen Gruppen abwickle.
Und da sage ich jetzt, ich summiere über die Städte, die Einwohner der
Städte in dieser Gruppe und dividiere das durch die Einwohnerzahl des
Landes.
Das ist ja gerade das, was ich wissen will, wenn diese Prozentzahl
praktisch größer als 0,1 ist, dann weiß ich also, mehr als 10% der
Stadt -Einwohner, mehr als 10% der Landeseinwohner wohnen in diesen
Großstädten.
Ich habe ja hier nur noch Großstädte.
So, jetzt nochmal ganz kurz, warum hier Einwohner steht.
Hier, Having arbeitet ja schon auf der Gruppe.
Das heißt, ich kann dort in der Gruppe auch nur zugreifen auf die
Attribute, die in der Gruppe vorhanden sind.
Und wenn ich dann hier die Gruppe betrachte, dann habe ich praktisch
den Namen des Landes und bräuchte dann auch noch die Einwohner des
Landes als eindeutigen Wert in der Gruppe, um die hier zu verwenden.
Was anderes ist es hier bei diesen Aggregierungsoperationen?
Da kann ich ja dann aufsummieren, wenn es da mehrere Werte gibt.
Also wenn ich hier Summ sage, Stadt, Punkt, Einwohner, ist das
überhaupt kein Problem, dass das hier nicht zur Gruppierung
hinzugezogen wird als Bedingung.
Das heißt, wenn ich das nämlich nicht in der Gruppierung habe, dann
heißt das ja, dass es in einer Gruppe dann in der Regel mehrere Werte
gibt dazu.
Und das macht hier gar nichts aus, das ist sogar gewollt hier, weil
ich hier nämlich dann eine Summe bilde, über sämtliche Einwohnerzahlen
der Städte, die in der Gruppe drin enthalten ist.
Aber an der Stelle hier dividiere ich ja durch die Einwohnerzahl des
Landes und da ist wichtig, dass ich da einen Wert habe.
Sonst weiß ich nicht, welchen Wert soll ich jetzt aus der Gruppe
nehmen.
Deswegen muss ich diese Einwohnerzahl hier in der Gruppe bei Klausel
mit aufnehmen.
So, okay.
Und dann könnte ich natürlich auch sowas noch machen.
Ich könnte mir auch noch die Quote als Ergebnis vorstellen, dass ich
das gerne haben wollte.
Dann nehme ich halt zu dem Landpunkt Name, das hier oben praktisch nur
da ist, nehme ich anschließend noch eine Summe über die
Stadteinwohner, durch die Landeinwohner.
Das lasse ich mir ausgeben als Ergebnis.
Also ich kann hier diese Aggregierungsoperation durchaus auch
verwenden wieder.
Auch in der Select-Klausel oben.
Gut.
So, jetzt haben wir schon sehr viel gemacht.
Ich habe hier jetzt noch SQL-Anfragen erstmal, die ich der Übung
überlassen will.
Hier zum Beispiel finden Sie die Namen aller Kunden, die Kunden von
allen Bibliotheken in der Datenbasis sind.
Das kann man sich einfach mal überlegen.
Also hier gibt es eine Bibliothek, hier gibt es Autoren, ein Buch gibt
es, Exemplare dieses Buches.
Also es gibt ja pro Buch eventuell mehrere Exemplare in der
Bibliothek, also solche Mehrfachexemplare.
Und deswegen brauche ich hier Exemplare und das Buch wäre praktisch
nur das ideelle Buch.
Also das ist das Buch Datenbankeinsatz von Lockmann und Lang zum
Beispiel.
Und das wäre also nicht das konkrete Buch, das man in der Hand hat,
das physische Buch, sondern das würde das Buch an sich beschreiben,
der Typ sozusagen.
Und die Exemplare, das sind tatsächlich die Teile, die man physisch in
der Hand hat, also die man wirklich ausleihen kann.
Deswegen dieser Unterschied hier, Bücher und Exemplare.
Es gibt Kunden und es gibt die Relation Laien, in der eine Leihnummer
existiert und da wird ein Exemplar von einem Kunden ausgeliehen und
zum bestimmten Datum dann abgegeben.
So, jetzt gibt es da also diese Anfragen und die kann man sich einfach
mal überlegen und bevor man dann die Lösung anguckt, lieber mal selber
ausprobieren.
Da möchte ich jetzt bei A nicht drauf geben.
Dann geht es hier darum, dass man mal so eine SQL-Anfrage sieht und
dann sich überlegt, was wird denn da überhaupt ausgedrückt.
Also wie würde ich das natürlich sprachlich als Anfrage formulieren
jetzt?
Was sagt denn diese Anfrage?
Da muss man sich halt anschauen, was wird denn gesucht?
Es werden anscheinend Buchtitel gesucht, wie es hier aussieht, aber
nicht für alle Bücher, sondern bestimmte Buchtitel.
Und welche Buchtitel?
Und da muss man dann schauen, was da gefragt ist hier und was da
nachher rauskommt.
Also anscheinend sind das irgendwelche Bücher, die ausgeliehen sind
und da muss man mal gucken, not exist, also die vielleicht noch nicht
ausgeliehen sind, muss man sich mal genau anschauen.
Also da geht es darum, dass man sich überlegt, was da rauskommt.
Dann finden Sie die Titel der Bücher, das war schon das Ergebnis, ja.
Dann geht es weiter.
Dann habe ich Anfragen mit Aggregierungsoperatoren nochmal, dass man
das ein bisschen üben kann.
Zum Beispiel für jeden Kunden
möchten wir die durchschnittliche Größe der Bibliotheken wissen.
Also pro Kunde wollen wir wissen, in welchen Bibliotheken leiht er
sich Bücher aus und was ist so die durchschnittliche Größe dieser
Bibliotheken.
Wie viele Räume sind es?
Leider hauptsächlich in sehr großen Bibliotheken aus oder leider in
sehr kleinen, in kleineren Bibliotheken aus, in Fachbibliotheken,
Institutsbibliotheken oder sowas.
Also so könnte man sich das vorstellen.
Und da soll man sich pro Kunde die Bibliotheken anschauen, in denen
der Kunde was ausleiht und soll dann anschauen, was ist denn so die
durchschnittliche Größe, also die durchschnittliche Anzahl der Räume
dieser Bibliotheken pro Kunde.
Das heißt, da muss man wohl wieder nach Kunden gruppieren, sieht man
mal schon.
Weil pro Kunde interessiert es ja.
Und dann muss man noch so einen Durchschnitt bilden, ein Average über
die Räume der Bibliotheken.
Und vorher muss man aber noch die richtigen Bibliotheken auswählen.
Also kann man sich mal anschauen, ob man da drauf kommt.
Hier kommt nochmal genau wieder das Umgekehrte.
Es wird ein SQL-Statement angegeben und man soll sich überlegen, was
wird denn damit ausgedrückt.
Also diese Art der Anfrage, die kommt sicher nicht in der Klausur vor,
weil natürlich, es kam zwar auch schon, aber es ist immer sehr
schwierig zu korrigieren.
Weil da natürlich, da muss man immer gucken, wie viel zieht man jetzt
ab, weil da irgendein Pünktchen oder irgendwas vielleicht nicht ganz
klar formuliert ist, und was ist jetzt nicht ganz klar oder so.
Aber ich denke, das ist einfach eine Aufgabestellung, wo man sich mal
selber Gedanken machen kann und versuchen kann zu überlegen, was macht
das SQL überhaupt, was macht diese Select-Anweisung.
Also insofern würde ich schon raten, dass man das mal versucht.
So, hier haben wir jetzt noch Änderungen.
Und da geht es jetzt darum,
Die Badischen Landesbibliothek in Karlsruhe hält ein neues Buch und es
hat dann irgendwie einen Titel und es ist von einer bestimmten Autorin
und es kostet einen bestimmten Betrag und hat so und so viele Seiten.
Das heißt, es sind alle wichtigen Angaben angegeben und die Autorin,
die soll schon in der Datenbasis vorhanden sein.
Also gehen wir mal davon aus, dass wir die nicht noch einfügen müssen.
Und jetzt soll man eben dieses neue Buch reinfügen in die Datenbasis
und wie geht man denn jetzt da vor, wie könnte man denn da jetzt
entsprechend ein Update dann mit SQL durchführen.
Und nicht ein Update der Datenbank, aber ein Insert-Befehl ist es
natürlich dann, weil ein neues Buch ja reinkommt.
Und das geht dann über ein Insert-Befehl und da muss man eben nicht
nur dieses Buch einführen, was ich vorhin ja erläutert habe, sondern
auch dann noch die physischen Exemplare.
Das wäre das, was hier unten dann passiert.
Und da muss man sich noch ein bisschen überlegen, was könnte es denn
vielleicht für Probleme geben, muss ich noch irgendwas vorher
ermitteln oder wie gehe ich da vor.
Insbesondere ist hier drauf eingegangen, dass man eigentlich so einen
Schlüssel da nicht unbedingt dem Benutzer überlassen möchte, dass der
den bestimmt.
Das heißt, man müsste vor dieser Insert, bevor man die Insert
-Operation absetzt, müsste man beispielsweise in dem
Anwendungsprogramm, um ein neues Buch einzufügen, müsste man noch
vorher so eine Schlüsselermittlung machen.
Und hier ist schon ein bisschen was dazu erzählt, wie man das machen
könnte, wenn man den dann hat.
Dann kann man dieses Buch einfügen und dann kann man anschließend noch
die Exemplare einfügen, die es gibt.
So, hier haben wir noch was.
Jetzt kommt ein Update.
Der Kunde möchte für sämtliche Bücher, die er in der Badischen
Landesbibliothek in Karlsruhe ausgeliehen hat, die Leitzeit um einen
Monat verlängern.
Und da habe ich jetzt auch sehr intuitiv nur natürlich die Angabe
gemacht.
Da müsste man wissen, wie das kodiert ist, die entsprechende
Abgabedatum.
Und dann könnte man natürlich dann rechnen da drauf.
Oder man müsste benutzerdefinierte Funktionen definieren und könnte
die dann verwenden in der Select-Anfrage.
Das würde in SQL 99 durchaus gehen.
Also hier geht es darum, wir machen Update Lion.
Das war die Relation.
Und hier kommt, was wir ändern wollen.
Das ist der Set-Befehl.
Der Set-Befehl sagt dann hier, was wird geändert.
Nämlich das Abgabedatum berechnet sich aus dem alten Abgabedatum.
Hier hat man also so eine Referenz auf das alte Tupel plus ein Monat.
Und wir wählen jetzt noch aus, welches Tupel wollen wir ändern.
Und das können wir hier halt über die K-Nummer beispielsweise dann
machen.
Das ist aber, glaube ich, der Kunde.
Doch, über die K-Nummer kriege ich ja hier geliefert, wenn ich hier
nur Lion betrachte und ich schränke nur ein auf die Bedingung K-Nummer
gleich 4711.
Dann kriege ich ja sämtliche ausgeliehenen Bücher des Kunden.
Und für sämtliche dieser Tupel wird dann diese Änderungsoperation
durchgeführt.
Die taucht hier offensichtlich nicht auf.
And.
Sehr gut.
Okay.
In Labi ausgeliehen.
Müsste man noch formulieren.
Das ist wichtig.
Richtig.
Genau.
Das fehlt hier.
Ansonsten würde man aber hier praktisch, da käme ich jetzt praktisch,
das ist nämlich das Interessante noch, genau, wollte ich nämlich
separat noch hinzufügen, dass man hier nämlich noch jetzt einen Bezug
nehmen muss auf andere Relationen.
So.
Dann kommt hier ein Beispiel zu Sichtendefinition.
Das habe ich auch relativ ausführlich beschrieben.
Und jetzt kommt noch die letzte Aufgabe, die möchte ich noch ganz kurz
angehen.
Und zwar geht es jetzt darum, dass man im objektorientierten
Datenmodell diese Relationen Patientkrankheit und Leidet an anschaut
und sich überlegt, wie man die denn umsetzen könnte in Objektklassen
und anschließend noch eine kleine Anfrage daran stellt.
Und da geht man halt jetzt so vor, dass man für die, ja, dass man
Klassen erzeugt für die einzelnen Relationen.
Denn in einer Relation sind ja entsprechende Tupel enthalten und diese
Tupel entsprechen bestimmten Objekten und die werden im
objektorientierten Fall eben in Klassen eingefügt.
Und in diesen Klassen, da gibt es dann, die sind hier auch als Extents
definiert, weil wir nämlich auch hier die,
wir möchten ja in der Relation Patient waren ja sämtliche Patienten
drin enthalten und dort ja die Schlüsselbedingungen auch definiert.
Das heißt, wir möchten hier in der Klasse Patient auch so ein Extent
Patienten haben und dort die Schlüssel wieder definieren.
Das können wir also hier an der Stelle machen, das würde uns praktisch
die Menge aller Patienten oder eine Extension von Patienten sozusagen
liefern.
Nämlich hier Patienten und der Schlüssel in dieser Menge von
Patienten, der wäre gleich Nummer.
Nummer ist hier definiert als Attribut, also bei den einfachen
Attributen, die in der Relation enthalten sind, ist es in der Regel
eine direkte, einfache Umsetzung.
Also das hier ist direkt, das hier ist direkt, das hier ist direkt.
Schlecht auch.
So, hier haben wir jetzt unten noch was, das habe ich noch nicht
abgehakt.
Jetzt gehen wir erstmal auf die Krankheit noch ein.
Bei Krankheit geht man genauso vor.
Name, Symptom, Ursache, Medikation sind auch wieder die einfachen
Attribute.
Und jetzt geht es darum, und der Schlüssel war wieder Name hier an der
Stelle, Nummer.
So, bis dahin ist alles okay.
Jetzt müssen wir aber noch die Beziehung, die zwischen den beiden
herrscht, möchten wir noch gerne darstellen.
Und da geht es jetzt darum, dass man praktisch hier ja zwischen
Patient und Krankheit eine Beziehung definieren kann, dass nämlich ein
Patient an bestimmten Krankheiten leidet.
Und das könnte man direkt im Patienten aufnehmen.
In so einer Relationship könnte man das hier zum Beispiel so
definieren.
Und zwar Relationship Krankheit wäre das an der Stelle.
Relationship Krankheiten.
Und das wäre vom Typ Krankheit.
Müsste aber an der Stelle eigentlich auch Set heißen.
Also ein Patient leidet ja in der Regel an mehreren Krankheiten.
Also hier bitte noch Set einfügen.
Also auf dem Übungsblatt ist dann schon richtig.
Hier Set einfügen.
Und dann geht man hier noch an, was ist denn so der inverse Weg.
Also wie komme ich jetzt von Krankheiten, wenn ich von einer Krankheit
ausgehe, von dieser Klasse Krankheit, wie komme ich denn dann auf die
Patienten.
Was ist also praktisch die Rückabbildung, die Rückbeziehung.
Das ist in diesem objektorientierten Fall also anders modelliert.
Dann hat man hier praktisch das inverse und würde dann hier sagen, ja
ich nehme die Klasse Krankheit, die ist hier unten definiert, und
nehme hier dann die Relationship betroffene Patienten, die habe ich
hier unten definiert.
Und das wäre praktisch meine inverse Beziehung.
Und hier ist praktisch genau die umgedrehte Darstellung.
Krankheiten wird hier vom Patienten genutzt.
Also das ist eine zweiseitige Beziehung.
Beziehung in zwei Richtungen modelliert sozusagen.
Also so könnte man dann sagen, dass man von den Krankheiten zu den
Patienten kommt und dass man von den Patienten sagt, an welchen
Krankheiten leidet er.
Und durch dieses inverse ist dann gewährleistet, dass das System weiß,
dass diese Beziehungen zusammenhängen.
Wenn hier praktisch betroffene Patienten drin enthalten sind, dann
muss bei diesem einen Patienten, der hier drin enthalten ist, das muss
natürlich auch, wenn wir dann in den Patienten reingehen, müssen wir
dann auch die entsprechende Krankheit wiederfinden.
Das wird dann automatisch vom System auch überwacht.
Also so könnte man das Leidet Anderen umsetzen und realisieren.
Hier ist noch als Abschluss dann eine ganz kleine OQL-Anfrage.
An welchen Krankheiten leidet der Patient Meier?
Und das können wir dann zum Beispiel so definieren.
Wir selektieren den Namen.
Das ist jetzt in OQL.
Das wurde aber nicht sehr ausführlich gemacht.
Ich gebe deshalb auch nur ein sehr einfaches Beispiel.
Und wir machen da auch nicht sehr viel drin.
Da müsste man dann in die Spezialvorlesung gehen.
Datenbankeinsatz beispielsweise, wo das sehr viel ausführlicher
behandelt wird.
Gut, da wird also der Name dann ausgegeben.
Von was?
Von dem Patienten.
Und von hier brauchen wir noch die Krankheiten, die der Patient hat.
Hier ist die Verknüpfung über einen Pfad gegeben.
Wir nehmen also einen Patienten und dann die Krankheiten dieses
Patienten.
Und hier ist die Einschränkung auf diese Klasse Patient, indem wir
nämlich sagen, wir interessieren uns nur für den Patienten mit dem
Namen Meier.
Genau für den Patienten mit dem Namen Meier.
Da kriegen wir dann entsprechend die Krankheiten raus.
Jetzt kann man sich noch überlegen, als Abschluss, was ist denn jetzt
der Ergebnistyp von dieser Select-Anweisung.
Und das kann man sich dann mal anschauen.
Und das wäre dann halt so ein BAG.
Das ist ja das Normale, was bei einer Select-Anweisung geliefert wird
in OQL.
Und ja, BAG von String.
Ja, dann praktisch.
Weil das Name ist ja ein String.
Also da wäre so eine ungeordnete Menge von Strings, die auch mehrfach
vorkommen können, die gleichen Strings.
Deswegen ein BAG.
Okay, jetzt wären wir durch.
Und wie gesagt, einfach mal üben und ausprobieren, weil sonst kriegt
man das SQL nicht rein.
Deswegen auch die anderen Anfragen noch.
Und das nächste Mal sehen wir uns dann zum Thema Datenbankentwurf und
Normalisierung. Tschüss.