WEBVTT

02:41.110 --> 02:46.090
Ja, wir haben ja gestern die relationalen Systeme abgeschlossen,

02:46.310 --> 02:47.970
insbesondere relationale Sprachen.

02:48.650 --> 02:51.330
Jetzt holen wir noch etwas nach, damit wir mal rückwärts gehen,

02:54.830 --> 02:59.030
nämlich das objektorientierte Datenmodell.

02:59.110 --> 03:01.430
Da werde ich etwas schneller durchgehen, vielleicht auch ein paar

03:01.430 --> 03:07.410
Folien überspringen, aber im Wesentlichen beschäftigen wir uns mit

03:07.410 --> 03:12.410
einem Problem oder mit einer Lösung für die Tatsache, dass drei

03:12.410 --> 03:14.470
verschiedene Forderungen aufeinander prallen.

03:14.950 --> 03:17.930
Und jetzt müssen wir irgendwie eine vernünftige Lösung finden, wie wir

03:17.930 --> 03:19.670
die drei Forderungen unter einen Hut bringen.

03:20.050 --> 03:22.930
Die erste Forderung kommt von der Anwendung her und sagt, naja, das

03:22.930 --> 03:25.630
relationale Datenmodell ist vielleicht doch nicht mächtig genug.

03:26.050 --> 03:31.150
Meine Umwelt oder meine Mini-Welt ist einiges komplizierter aufgebaut

03:31.150 --> 03:34.070
und die in das Korsett von Relationen zu pressen, das ist doch ein

03:34.070 --> 03:34.910
bisschen zu einfach.

03:36.750 --> 03:40.510
Das war übrigens auch der Anfang der objektorientierten Datenmodelle

03:40.510 --> 03:44.430
im Datenbankbereich und zwar im Konstruktionsbereich hat das begonnen.

03:44.670 --> 03:48.790
Im Konstruktionsbereich ist man eigentlich mit dem relationalen Modell

03:48.790 --> 03:53.830
recht schnell unzufrieden gewesen, weil die Überführung der

03:53.830 --> 03:57.750
Verhältnisse in der Mini-Welt in das sehr einfache Datenmodell,

03:57.850 --> 04:01.410
relationale Datenmodell einfach zu sehr komplizierten Konstruktionen

04:01.410 --> 04:03.930
gefunden hat, die gar nicht mehr für sich selbstverständlich waren.

04:04.170 --> 04:06.490
Man muss da immer eine Menge dokumentieren, um dazu zu sagen, was

04:06.490 --> 04:08.610
eigentlich jetzt hinter den Relationen steckte.

04:09.430 --> 04:15.490
Die zweite Forderung kommt aus der Ecke der Programmiersprachen.

04:17.230 --> 04:20.130
Irgendwann ist man mal dahinter gekommen, dass man Objekte auch

04:20.130 --> 04:22.590
persistent machen will, also dauerhaft machen will, nach unserer

04:22.590 --> 04:23.250
Terminologie.

04:24.130 --> 04:27.810
Und dann kam also der Begriff der persistenten objektorientierten

04:27.810 --> 04:28.730
Sprachen auf.

04:30.390 --> 04:32.750
Und da hat man sich den Problemen im Wesentlichen von der

04:32.750 --> 04:36.010
programmiersprachlichen Seite aus genähert und hat dann gesagt, wir

04:36.010 --> 04:39.510
wollen in der Lage sein, Objekte auch persistent zu machen, ohne dass

04:39.510 --> 04:42.270
wir, wie das sonst üblicherweise im Bereich der Programmiersprachen

04:42.270 --> 04:45.150
der Fall ist, erst noch aufwendig durch die Dateiverwaltung gehen und

04:45.150 --> 04:46.670
dann seine eigenen Dateien verwalten muss.

04:47.690 --> 04:52.810
Und die dritte Seite war die Datenbankwelt, die im Grunde genommen

04:52.810 --> 04:55.790
immer mit diesem Problem des Impedance-Mismatch, das ich ja gestern

04:55.790 --> 04:59.190
vorgeführt habe, sich rumzuschlagen hat und gesagt hat, vielleicht

04:59.190 --> 05:03.010
können wir dem Problem etwas entkommen, indem wir Programmiersprachen

05:03.010 --> 05:07.010
und Datenbanksystemen etwas enger aneinander binden oder etwas stärker

05:07.010 --> 05:07.370
koppeln.

05:08.430 --> 05:12.190
Und wenn ich also jetzt Ihnen hier vorführe, wie man sogar

05:12.190 --> 05:15.970
standardisiert rangegangen ist an dieses Problem, dann werden wir

05:15.970 --> 05:19.050
immer wieder nachsehen, wo steckt eigentlich jetzt welche Forderung

05:19.050 --> 05:20.150
hin, welcher kommen wir entgegen.

05:21.990 --> 05:24.770
Sie werden auch noch eine ganze Menge Ähnlichkeiten mit Java

05:24.770 --> 05:25.290
entdecken.

05:26.690 --> 05:30.390
Das wurde davon her, nicht einmal, dass man zu jener Zeit von Java

05:30.390 --> 05:32.950
schon so überzeugt gewesen wäre, als man das Modell entwickelt hat,

05:33.310 --> 05:38.970
aber dass die Autoren von Java, der ursprünglichen Fazit von Java und

05:38.970 --> 05:42.390
das ODMG-Standard, das ich Ihnen vorführen werde, aus der gleichen

05:42.390 --> 05:42.850
Ecke kommen.

05:42.850 --> 05:43.810
Beide kamen von Sun.

05:44.930 --> 05:48.650
Und auch wenn sie nicht personengleich waren, so waren offenbar doch

05:48.650 --> 05:51.390
die Beziehungen zwischen diesen Gruppen sehr eng. Und man empfindet

05:51.390 --> 05:52.690
also eine ganze Menge Ähnlichkeiten.

05:54.670 --> 05:58.430
So, wir gehen als erstes wieder los und schauen uns erstmal an, wie

05:58.430 --> 06:01.530
können wir eigentlich mit objektorientierten Systemen, wie können wir

06:01.530 --> 06:02.110
die beschreiben?

06:02.630 --> 06:05.650
Die Motivation habe ich Ihnen schon geliefert und die wesentlichen

06:05.650 --> 06:07.150
Merkmale, da brauche ich nichts dazu zu sagen.

06:07.430 --> 06:10.870
Natürlich will man auch im Datenbankbereich nicht plötzlich zwar von

06:10.870 --> 06:13.670
Objektorientierung sprechen, macht man an manchen Stellen sehr wohl,

06:14.130 --> 06:18.430
ohne wirklich das Gleiche zu meinen, wie etwa diejenigen, die aus der

06:18.430 --> 06:20.910
Programmiersprachenecke kommen, aus der ja ursprünglich auch die

06:20.910 --> 06:21.870
Objektorientierung stammt.

06:22.170 --> 06:25.250
Also wir nehmen auch von den Programmiersprachen das

06:25.250 --> 06:28.770
Kapselungsprinzip, wir werden gleich sehen, dafür halten wir sogar

06:28.770 --> 06:29.910
sehr stringent durch.

06:30.750 --> 06:34.670
Wir verfolgen eigentlich die Objektentität mit der Referenzsemantik.

06:35.230 --> 06:40.690
Wir wollen Vererbung verwenden können, und zwar, wie wir sehen werden,

06:41.250 --> 06:43.990
wird eine wesentliche Rolle spielen, um doch polymorphe Eigenschaften

06:43.990 --> 06:46.790
zu erreichen, denn das objektorientierte Modell ist ja von Natur aus

06:46.790 --> 06:48.310
zunächst mal monomorph und nicht polymorph.

06:49.230 --> 06:52.430
Wir können aber in gewissem Umfang die Polymorphie nachbilden, das

06:52.430 --> 06:53.650
werde ich auch zeigen.

06:54.450 --> 06:58.050
Und die Polymorphie basiert im Wesentlichen darauf, dass wir Vererbung

06:58.050 --> 07:01.130
geschickt einsetzen und hinter der Vererbung steckt wieder das

07:01.130 --> 07:05.210
Substituierbarkeitsprinzip, nämlich ich kann an jeder Stelle, an der

07:05.210 --> 07:11.290
ich ein Objekt eines bestimmten Typs erwarte, durch die Typdefinition

07:11.290 --> 07:16.830
einer Variablen, kann ich jederzeit auch ein Objekt substituieren oder

07:16.830 --> 07:20.190
einen Verweis reinsetzen auf ein Objekt, das ein Untertyp dieses so

07:20.190 --> 07:21.330
vereinbarten Typs ist.

07:21.850 --> 07:24.430
Das liegt an der Vererbung, weil auf jeden Fall der Untertyp ja

07:24.430 --> 07:26.790
garantiert zumindest die Eigenschaften des Obertyps besitzt.

07:27.410 --> 07:29.010
Und davon werden wir eben auch Gebrauch machen.

07:31.710 --> 07:35.230
So, jetzt schauen wir uns mal an, wie das Typsystem aussieht.

07:36.190 --> 07:39.730
Und da muss ich zunächst mal sagen, wir beziehen uns in der Tat auf

07:39.730 --> 07:45.910
einen Standard, der Object Database Management Group, ODMG.

07:46.990 --> 07:52.250
Der ist in einer Version 2.0, glaube ich, 92, 93 erschienen.

07:52.910 --> 07:53.830
Ne, später erschienen.

07:54.410 --> 07:58.710
Die jetzige Version 3.0 stammt aus dem Jahr 2000.

07:58.850 --> 08:02.030
Wer sich für Details interessiert, wir führen überall die

08:02.030 --> 08:05.590
entsprechenden Bücher und Literatur in der Informatikbibliothek.

08:05.590 --> 08:08.670
Dort finden Sie auch nähere Angaben zu ODMG 3.0.

08:10.010 --> 08:15.050
Und ich beziehe mich im Wesentlichen jetzt auf ODMG 3.0, denn lange

08:15.050 --> 08:18.710
Zeit war ein Hindernis dafür, dass sich objektorientierte Datenbanken

08:18.710 --> 08:21.710
nicht durchgesetzt haben, der Mangel an Standards.

08:22.170 --> 08:25.810
Und die Industrie setzt heute keine Produkte mehr ein, bei denen nicht

08:25.810 --> 08:27.210
Standards garantiert sind.

08:27.330 --> 08:30.530
Zumindest dann, wenn man erwarten kann, dass Standards existieren

08:30.530 --> 08:30.850
müssten.

08:32.950 --> 08:36.010
Der Standard ist relativ spät entstanden, dummerweise zu einem

08:36.010 --> 08:37.630
Zeitpunkt, an dem wir rechts und rechts diesen Projekte aus den

08:37.630 --> 08:40.490
Datenbanksystemen spielen, ein gewisses Nischen-Dasein.

08:41.270 --> 08:44.210
Außer, dass sie heute bei sogenannten objektrelationalen Systemen

08:44.210 --> 08:47.630
wieder eine zunehmende Rolle spielen, aber dann den relationalen

08:47.630 --> 08:48.790
Systemen untergeordnet sind.

08:49.270 --> 08:51.610
Aber ich glaube trotzdem, es ist gut, mal hier durchzugehen durch den

08:51.610 --> 08:54.950
Standard, weil wir sehen, was die wesentlichen Faktoren sind, die dann

08:54.950 --> 08:57.770
versuchen, irgendwie einen Kompromiss zwischen diesen drei

08:57.770 --> 09:05.630
Forderungen, die ich beschreibe, nämlich zwischen Literalen und

09:05.630 --> 09:06.050
Objekten.

09:07.270 --> 09:10.290
Und im Wesentlichen kann man sagen, bei den Literalen wird eine

09:10.290 --> 09:14.510
Kopiersemantik unterstellt, das heißt also, der Wert steht auch für

09:14.510 --> 09:18.950
das, kann man jetzt nicht sagen für das Objekt, aber für den

09:18.950 --> 09:21.390
Gegenstand, den wir hier beschreiben, für die Instanz.

09:21.890 --> 09:25.390
Während bei Objekten geben wir, wie das so üblich ist, einen

09:25.390 --> 09:28.010
eindeutigen Identifikator mit auf den Weg.

09:28.530 --> 09:31.050
Das heißt, jedes Objekt ist einfach durch seinen Objektidentifikator

09:31.050 --> 09:31.910
identifiziert.

09:32.070 --> 09:34.270
Und dahinter steckt dann ganz offensichtlich eben eine

09:34.270 --> 09:35.210
Referenzsemantik.

09:36.910 --> 09:40.650
Nun kann man sich darüber streiten, ob man wirklich die Unterscheidung

09:40.650 --> 09:43.930
zwischen Literalen, deren Domänen dann als Sorten bezeichnet werden,

09:44.410 --> 09:48.510
treffen muss und Objekten, oder ob man das nicht unter einen Hutpacken

09:48.510 --> 09:49.070
packen kann.

09:49.170 --> 09:51.730
Und es gibt auch Programmiersprachen, die tatsächlich diese

09:51.730 --> 09:54.450
Unterscheidung fallen lassen, die alles und jedes als Objekt

09:54.450 --> 09:57.690
betrachten, zumindest aus der Sicht des Benutzers.

09:58.070 --> 10:00.330
Ein berühmtes Beispiel ist Smalltalk, eine der ältesten

10:00.330 --> 10:01.990
objektorientierten Sprachen überhaupt.

10:01.990 --> 10:05.450
Bei der ODMG wird also schon bewusst unterschieden zwischen Literalen,

10:05.850 --> 10:08.950
also solchen, bei denen der Wert für die Identifikation steht, wenn

10:08.950 --> 10:12.690
wir die Kopiersemantik verwenden, und Objekten, so wie Sie sie auch

10:12.690 --> 10:15.710
kennen, die über einen Objektidentifikator verfügen, bei denen eine

10:15.710 --> 10:17.190
Referenzsemantik unterstellt wird.

10:19.430 --> 10:22.950
Es gibt Sprachanbindungen, wie gesagt, wenn Sie zum Beispiel ODMG

10:22.950 --> 10:26.290
anschließend als Smalltalk anbinden müssen, dann wird der Unterschied

10:26.290 --> 10:29.650
wieder verwischt, während in anderen Sprachen der Unterschied auch

10:29.650 --> 10:30.610
aufrechterhalten wird.

10:30.610 --> 10:33.410
Jetzt lasse ich noch das Wort Sprachanbindung fallen, dann komme ich

10:33.410 --> 10:35.970
vielleicht nachher nochmal drauf, was da hinter sich genau verbirgt.

10:37.130 --> 10:42.910
Wir können also sagen, dass wenn wir die Mengen von Objekten gleichen

10:42.910 --> 10:46.130
Typs betrachten, dann haben wir eine Klassendefinition, wir werden

10:46.130 --> 10:50.270
also die Klassen als die Typen für die Objekte bezeichnen und die

10:50.270 --> 10:53.450
Sorten als die Domänen für die Literale.

10:53.970 --> 10:56.070
Aber wir werden bald sehen, wir werden noch eine Unterschiede machen,

10:56.530 --> 10:58.930
die aber ähnlich ist, wie Sie das von Java gewohnt sind.

11:03.290 --> 11:06.990
Häufig wird man irgendwie auch eine Brücke zwischen der relationalen

11:06.990 --> 11:08.910
und der objektorientierten Welt schlagen müssen.

11:09.270 --> 11:11.950
Das ist heute sogar sehr weit der Fall.

11:12.950 --> 11:15.610
Und dann ist es natürlich immer ganz sinnvoll, sich mal anzusehen, was

11:15.610 --> 11:18.030
sind jetzt eigentlich die wesentlichen Unterschiede zwischen den

11:18.030 --> 11:18.430
beiden.

11:19.130 --> 11:23.410
Wir sehen schon mal, zwischen Literalen und Objekten wird ein

11:23.410 --> 11:27.070
Unterschied gemacht, den gibt es natürlich nicht in relationalen

11:27.070 --> 11:27.350
Systemen.

11:27.370 --> 11:29.370
Man kann sogar sagen, in relationalen Systemen gibt es überhaupt

11:29.370 --> 11:31.790
keinen Objektidentifikator, also gibt es eigentlich auch keinen

11:31.790 --> 11:32.530
Klassenbegriff.

11:33.830 --> 11:38.170
Und die Identität in relationalen Systemen wird durch den Schlüssel

11:38.170 --> 11:42.510
diktiert, also durch einen Wert, der, wie wir gestern gehört haben,

11:42.550 --> 11:47.890
durchaus auch geändert werden kann, während der Objektidentifikator,

11:48.010 --> 11:51.910
der einem Objekt mitgegeben wird, über die Lebensdauer des Objektes

11:51.910 --> 11:53.330
unveränderlich bleibt.

11:55.210 --> 11:57.830
Wenn Sie ein objektorientiertes Programm nehmen, dann ist es Ihnen

11:57.830 --> 12:02.810
ziemlich egal, die Lebensdauer ist definiert über die Dauer des

12:02.810 --> 12:06.310
Programmlaufs und danach können Sie den Objektidentifikator vergessen

12:06.310 --> 12:08.750
und er kann also auch wieder neu verwendet werden.

12:08.990 --> 12:11.770
Aber im Datenbanksystem, wenn ich sage, über die ganze Lebensdauer

12:11.770 --> 12:14.890
muss der Objektidentifikator eindeutig sein, dann können Sie sich mal

12:14.890 --> 12:17.990
überlegen, was für einen monströsen Aufwand Sie allein im

12:17.990 --> 12:21.170
Datenbanksystem treiben müssen, um sicherzustellen, dass Sie nie,

12:21.350 --> 12:24.470
vielleicht über 50 oder 100 Jahre, den gleichen Objektidentifikator

12:24.470 --> 12:25.270
noch mal vergeben.

12:25.710 --> 12:28.370
Und noch schlimmer wird es, wenn Sie ein verteiltes System haben und

12:28.370 --> 12:31.710
Sie auch noch in einem ganzen Netz, netzweit, sicherstellen müssen,

12:31.830 --> 12:33.610
dass der Objektidentifikator eindeutig ist.

12:34.110 --> 12:39.710
Also diese harmlose Forderung, dass über die Lebensdauer der

12:39.710 --> 12:44.690
Objektidentifikator unverändert bleibt, die ist im Datenbankbereich

12:44.690 --> 12:47.810
wegen der langen Lebensdauer und der Größe der Datenbasen plötzlich

12:47.810 --> 12:49.190
eine ganz massive Forderung.

12:49.590 --> 12:51.430
Frisst auch sofort Leistung weg, dummerweise.

12:53.070 --> 12:55.490
Und zwar an eine Ecke, wo man das gar nicht so unbedingt erwartet.

12:58.010 --> 13:00.930
Der Objektidentifikator dient dann aber auch als klassische Referenz.

13:01.550 --> 13:04.190
Sie kriegen ihn auch wieder nie zu sehen, sondern Sie können nur seine

13:04.190 --> 13:05.130
Existenz unterstellen.

13:06.610 --> 13:09.910
Aber er wird an allen Stellen, an denen Sie einen Verweis auf ein

13:09.910 --> 13:14.830
Objekt setzen, wird eben der Objektidentifikator eingetragen.

13:14.830 --> 13:16.650
So, also das ist schon das erste Problem.

13:17.130 --> 13:18.270
Er ist unverändert.

13:18.390 --> 13:21.570
Da gibt es sogar noch kriminellere Probleme, die besagen, darf ich

13:21.570 --> 13:24.990
eigentlich einen Objektidentifikator, wenn ich ein Objekt gelöscht

13:24.990 --> 13:26.250
habe, darf ich ihn dann wieder verwenden?

13:29.530 --> 13:31.390
Da schweigt man sich etwas aus.

13:32.350 --> 13:36.490
Es gibt also sehr harte Forderungen gelegentlich im Systembereich,

13:37.070 --> 13:40.190
dass man sagt, nein, er darf nicht mal mehr wiederverwendet werden,

13:40.510 --> 13:43.650
weil ja die Gefahr besteht, dass nicht alle Referenzen beseitigt

13:43.650 --> 13:48.110
werden, weil Sie gar nicht wissen, wo, an welchen Stellen jetzt auf

13:48.110 --> 13:50.430
das Objekt, das Sie gerade gelöscht haben, verwiesen wird.

13:50.790 --> 13:53.330
Und dann haben Sie eine sogenannte Insleerzelehre, zeigen der

13:53.330 --> 13:57.030
Referenz, oder dangling reference, und wenn dann stattdessen ein neues

13:57.030 --> 13:59.550
Objekt inzwischen die Subjektreferenz bekommen hat, dann haben Sie

13:59.550 --> 14:04.230
eine völlig verdrehte Semantik, nämlich Sie nehmen an, dass die noch

14:04.230 --> 14:07.450
gültig ist, diese Referenz werden in Wirklichkeit gar nicht mehr

14:07.450 --> 14:10.170
zutrifft und auf jeden Fall nicht für dieses neue Objekt zutrifft.

14:10.170 --> 14:13.890
Also gibt es Forderungen, die sagen, man darf ein Objektidentifikator

14:13.890 --> 14:16.310
nur ein einziges Mal systemweit vergeben.

14:16.950 --> 14:19.670
Jetzt können Sie sich erst recht den Aufwand vorstellen, der mit der

14:19.670 --> 14:22.670
Verwaltung solcher Identifikatoren einhergeht, und noch schlimmer als

14:22.670 --> 14:25.090
bald können Sie sich auch vorstellen, wie viel Beiz Sie brauchen, um

14:25.090 --> 14:28.910
diese Eindeutigkeit über 10, 20, 50 Jahre aufrecht zu erhalten,

14:29.050 --> 14:31.270
insbesondere dann, wenn die Datenbasen sehr groß sind.

14:31.570 --> 14:35.230
Also diese harmlose Forderung hinter der versteckt sich unter

14:35.230 --> 14:37.210
Umständen ein ganz enormer Aufwand.

14:38.370 --> 14:43.610
So, jetzt wird auch vorgeschrieben, wie das Modell aussehen soll, und

14:43.610 --> 14:47.690
wir sehen hier, dass wir im Wesentlichen erstmal eine Menge atomarer

14:47.690 --> 14:52.690
Typen vorgeben, dann erlauben wir außerdem noch den Aufzählungstyp,

14:53.290 --> 14:56.770
dann haben wir auch gewisse strukturierte Typen, nämlich Date, Time,

14:56.870 --> 14:57.990
Timestamp und Interval.

14:58.370 --> 15:01.170
Da kann man sich gut vorstellen, dass man bei Time etwa Stunden,

15:01.290 --> 15:06.430
Minuten unterscheiden kann, oder bei Date Tag, Monat, Jahr.

15:07.190 --> 15:11.730
Und diese Struktur ist in der Tat so gegeben, dass Sie einzeln nach

15:11.730 --> 15:13.030
diesen Teilen abfragen können.

15:14.450 --> 15:20.490
Sind aber auch, sind a priori vorgegeben, also haben wir hier

15:20.490 --> 15:22.090
monomorphe Typen.

15:22.910 --> 15:26.590
Und dann gibt es wieder Typkonstruktoren, die uns jetzt in den Bereich

15:26.590 --> 15:31.170
der polymorphen Typen bringen, die wir dann jeweils wieder zu

15:31.170 --> 15:33.170
instanziieren haben, zu monomorphen Typen.

15:33.550 --> 15:38.450
Und da gibt es jetzt mehr als einen Konstruktor.

15:38.550 --> 15:40.830
Zunächst mal gibt es den Konstruktor, den wir schon kennen, jetzt

15:40.830 --> 15:44.450
heißt er halt mal zur Abwechslung Struct, läuft im Wesentlichen darauf

15:44.450 --> 15:49.070
hinaus, wiederum sowas wie ein Rekordtyp zu definieren.

15:49.950 --> 15:54.410
Allerdings, wenn Sie sich das ansehen, dann steht hier Typ.

15:55.690 --> 15:59.830
Und Typ ist die Vereinigungsmenge aller Typen, die sich überhaupt

15:59.830 --> 16:00.430
vereinbaren können.

16:00.530 --> 16:02.550
Neutrale oder Klassen.

16:03.210 --> 16:06.970
Das heißt, wir können an dieser Stelle jetzt beliebige Strukturen

16:06.970 --> 16:10.610
wiederum als Komponenten einfügen und jetzt kriegen wir keine flachen

16:10.610 --> 16:13.290
Strukturen, wie bei Relationen mehr, sondern beliebig tief

16:13.290 --> 16:16.990
verschachtelte Strukturen mit beliebigen Verweisen irgendwo anders

16:16.990 --> 16:17.190
hin.

16:18.070 --> 16:20.530
Und das kann man sich gleich vorstellen, das macht natürlich später,

16:20.570 --> 16:24.350
wenn man mal solche Strukturen speichern will, die Aufgaben der

16:24.350 --> 16:27.910
Implementierung weit, weit komplizierter als im Fall der Relation, wo

16:27.910 --> 16:29.670
man einfach mit seinen flachen Sätzen arbeitet.

16:31.750 --> 16:35.450
So, und dann haben wir jetzt drei Mengenkonstruktoren.

16:35.570 --> 16:36.550
Wir haben natürlich wieder die Menge.

16:36.830 --> 16:39.370
Im Datenbankbereich ist ganz klar, dass wir mit Mengen arbeiten

16:39.370 --> 16:39.730
wollen.

16:40.230 --> 16:43.930
Wir haben einen reinen klassischen Mengenoperator, der erzeugt also

16:43.930 --> 16:45.470
das, was wir gewohnt sind, als eine Menge.

16:48.890 --> 16:53.110
Jedes Objekt kann nur einmal vorkommen, aber wir bedenken Sie, das

16:53.110 --> 16:55.630
Objekt ist nur gekennzeichnet eindeutig durch seinen

16:55.630 --> 16:56.570
Objektidentifikator.

16:56.730 --> 16:58.550
Also gleiche Werte können durchaus mehrfach vorkommen.

17:01.130 --> 17:05.690
Wenn wir bei Typ aber nur Literale haben, dann ist eindeutig, dass

17:05.690 --> 17:08.150
auch der Wert nur einmal vorkommen darf, denn der dient ja selbst der

17:08.150 --> 17:08.950
Identifikation.

17:09.570 --> 17:12.770
So, und dann lassen wir aber auch zu, dass wir, so wie wir das aus den

17:12.770 --> 17:16.170
Relationen kennen, auch mal non-distinct sind.

17:16.610 --> 17:20.190
Also die gleichen Elemente mehrfach vorkommen können, entsprechend von

17:20.190 --> 17:21.070
einem sogenannten Bag.

17:21.750 --> 17:22.570
Das ist eine Multimenge.

17:23.470 --> 17:25.470
Und dann können wir auch noch eine Ordnung aufprägen.

17:25.570 --> 17:29.790
Wir können also auch Mengen, in dem Fall Bags übrigens, als geordnet

17:29.790 --> 17:30.490
ansehen.

17:30.730 --> 17:32.170
Und dann kommen wir zu einer Liste.

17:34.410 --> 17:37.430
Also das ist so, was wir im Literalbereich tun können.

17:37.490 --> 17:40.530
Da können wir schon enorm komplizierte Strukturen aufbauen, aber wir

17:40.530 --> 17:43.470
hatten ja gesagt, wir brauchen mehr Mächtigkeit als im relationalen

17:43.470 --> 17:46.810
Bereich, weil wir ja Minivelten zu tun haben, die viel komplizierter

17:46.810 --> 17:47.630
strukturiert sind.

17:48.130 --> 17:51.530
Also stellen Sie sich nur vor, da ging es nämlich los damit, die

17:51.530 --> 17:54.710
ersten Systeme dieser Art sind im VLSI-Entwurf aufgetaucht.

17:55.430 --> 17:57.690
Und so ein VLSI-Entwurf, stellen Sie sich mal so einen Chip vor, auch

17:57.690 --> 18:02.970
wenn der vor 20 Jahren noch viel einfacher war als heute, der hat

18:02.970 --> 18:06.290
natürlich selbst eine sehr komplizierte Unterstruktur und die kann man

18:06.290 --> 18:08.030
ganz gut auf diese Weise nachbilden.

18:12.230 --> 18:16.690
So, da traue ich nicht viel dazu zu sagen, außer noch eins, dass wir

18:16.690 --> 18:21.230
als elementaren Typ auch noch Verweise zulassen.

18:21.690 --> 18:26.150
Dann haben wir also ein Ref und wenn wir ein Ref verwenden, dann wird

18:26.150 --> 18:30.410
davon ausgegangen, dass das Ziel des Verweises immer ein Objekt ist

18:30.410 --> 18:33.050
und infolgedessen wird an der Stelle ein Objekt-Identifikator

18:33.050 --> 18:33.610
eingetragen.

18:34.250 --> 18:38.890
Und das gleiche können wir jetzt auch für Objekte einführen.

18:39.310 --> 18:47.510
Bei Objekten gibt es nochmal Atomare Typen, die strukturiert sind und

18:47.510 --> 18:51.670
die man entweder durch ihren Wert oder aber auch als Objekte einführen

18:51.670 --> 18:51.950
kann.

18:52.110 --> 18:54.790
Nämlich genau die vier, die ich vorhin als strukturierte Typen

18:54.790 --> 18:58.530
eingeführt habe, bei den Literalen, können auch Objekteigenschaft

18:58.530 --> 19:00.790
erfahren, muss ich halt ausdrücklich sagen, dass das als Objekt

19:00.790 --> 19:01.410
erzeugt wird.

19:01.890 --> 19:04.170
Nämlich Date, Time, Timestamp und Interval.

19:04.970 --> 19:07.910
Und wer genau hingesehen hat, der sieht, dass ich jetzt halt

19:07.910 --> 19:11.610
Großschreibung verwende, wenn es sich um einen Objekttyp handelt und

19:11.610 --> 19:13.530
Kleinschreibung, wenn es sich um einen Literaltyp handelt.

19:14.210 --> 19:19.190
Und dann finden wir genauso wiederum, wie im Bereich der Literale,

19:19.330 --> 19:25.610
wieder einmal die Konstruktion eines strukturierten Typs, Stuppentyps

19:25.610 --> 19:31.210
mit kompliziert strukturierten Elementen.

19:31.470 --> 19:35.010
Nämlich hier wird es als Objekt bezeichnet und wir sehen wiederum,

19:35.150 --> 19:40.090
dass wir alles zulassen, sämtliche Literaltypen, sämtliche Objekttypen

19:40.090 --> 19:41.750
können an dieser Stelle verwendet werden.

19:41.870 --> 19:44.830
Das heißt, wir können in der gleichen Weise, so wie wir Strukturen,

19:45.910 --> 19:49.490
die eine Wertesemantik haben, so können wir auch mit einer

19:49.490 --> 19:52.990
Referenzsemantik Objekte erzeugen, die entsprechend kompliziert

19:52.990 --> 19:53.810
strukturiert sind.

19:54.030 --> 19:57.470
Und dann haben wir wieder alle drei Mengenkonstruktionen, Set, Bag,

19:57.590 --> 20:02.090
List, die wiederum, wie zuvor auch, entweder selbst wieder aus

20:02.090 --> 20:05.370
Objekten bestehen können oder die Mengen können auch wiederum aus

20:05.370 --> 20:06.450
Literalen bestehen.

20:07.390 --> 20:10.470
Sie sind nur immer vom gleichen Typ, wie wir das auch von Relationen

20:10.470 --> 20:15.910
gewohnt sind und lediglich werden diese Mengen, Bags und Listen eben

20:15.910 --> 20:17.390
jetzt als Objekte definiert.

20:18.550 --> 20:21.590
Also da muss man sich ansehen, braucht man jetzt ein Literal oder

20:21.590 --> 20:22.230
braucht man ein Objekt?

20:22.390 --> 20:24.430
Das ist eine Entscheidung, die treffen wir im Datenbankbereich gar

20:24.430 --> 20:24.530
nicht.

20:24.650 --> 20:27.270
Das soll der Benutzer gefälligst entscheiden, was er an der Stelle

20:27.270 --> 20:27.770
haben will.

20:27.850 --> 20:29.250
Aber er muss sagen, was er haben will.

20:29.910 --> 20:34.430
Und wir stellen ihm hier diese Werkzeuge, also diese Strukturen, diese

20:34.430 --> 20:36.470
Definition, diese Typkonstrukturen zur Verfügung.

20:37.390 --> 20:47.410
Und jetzt brauchen wir noch etwas, zunächst einmal Set, Bag und List

20:47.410 --> 20:53.870
sagen ja nur, dass man irgendeine Menge erzeugt konstruieren kann aus

20:53.870 --> 20:55.830
Elementen eines bestimmten Typs.

20:56.310 --> 20:58.670
Und zwar assembliche Elemente müssen vom gleichen Typ sein.

20:58.670 --> 21:04.890
Sie sagt aber noch nichts darüber aus, ob wir Objekte des gleichen

21:04.890 --> 21:07.890
Typs nur in einer einzigen Menge, wie wir das von der Relation her

21:07.890 --> 21:11.230
kennen, oder auf beliebig viele Typen verteilen können.

21:11.930 --> 21:18.150
Von der Definition her können wir also mehrere Sets definieren, die

21:18.150 --> 21:21.490
alle Elemente, zum Beispiel wenn es aus Objekttypen besteht, Objekte

21:21.490 --> 21:25.730
aufnehmen, die alle Elemente des gleichen Objekttyps verwenden.

21:25.730 --> 21:31.630
Aber wir können uns den Relationen etwas annähern, indem wir noch eine

21:31.630 --> 21:35.950
zusätzliche Konstruktion, und zwar den Extent, einführen.

21:36.330 --> 21:41.450
Der Extent, wenn wir sagen, wir konstruieren ein Extent, dann wird

21:41.450 --> 21:47.150
automatisch, sobald wir das spezifiziert haben, werden alle Objekte

21:47.150 --> 21:51.870
eines bestimmten Objekttyps, jetzt sind wir beschränkt, sämtlichen in

21:51.870 --> 21:54.790
der Datenbasis liegen diesem Extent zugeordnet.

21:55.490 --> 21:58.150
Und jetzt können Sie sich vorstellen, ich kann also in der Tat so

21:58.150 --> 22:01.750
einen Sprung machen von Relationen in die Objektorientierung und

22:01.750 --> 22:03.770
zurück über die Konstruktion des Extents.

22:03.870 --> 22:06.430
Ich kann also eine Relation selbst, von ihren ganzen Eigenschaften, es

22:06.430 --> 22:11.290
gibt genau einen Extent, der alle Objekte dieses Typs aufnimmt, das

22:11.290 --> 22:13.350
entspricht also tatsächlich unserer Vorstellung der Relation.

22:14.530 --> 22:17.630
Das ist ein typisches Konstrukt, das die Datenbankleute eingeschleppt

22:17.630 --> 22:17.910
haben.

22:18.390 --> 22:21.390
Die Programmiersprachleute haben nicht den geringsten Bedarf an einem

22:21.390 --> 22:21.870
Extent.

22:21.870 --> 22:26.170
Aber wir werden gleich sehen, das spielt eine ganz erhebliche Rolle,

22:26.310 --> 22:29.950
auch dann für die Anfragesprachen, wie es euch interessiert, so etwas

22:29.950 --> 22:33.350
aus unserer gewohnten relationalen Welt heraus, die Eigenschaften

22:33.350 --> 22:35.310
festzulegen und dann wird eben so ein Extent eingeführt.

22:36.710 --> 22:39.590
Das ist also eine Besonderheit, weil man dem Extent dann auch noch

22:39.590 --> 22:41.090
einige Eigenschaften anbinden kann.

22:43.770 --> 22:48.750
So, das brauche ich eigentlich nicht zu wiederholen, außer dass ich

22:48.750 --> 22:51.630
für die Schreibweise in dem Gehen ein bisschen was anderes verwende.

22:51.790 --> 22:56.130
Wir werden also hier das Wort Set, Bag, List, Array gibt es auch noch

22:56.130 --> 22:58.190
und Dictionary, auf die gehe ich jetzt nicht näher ein.

22:59.050 --> 23:04.190
Das sind auch Mengenkonstruktionen, dass wir dann eben einfach diese

23:04.190 --> 23:06.830
Begriffe verwenden, statt die Schreibweise, die ich gerade vorhin

23:06.830 --> 23:07.910
verwendet habe.

23:09.970 --> 23:13.430
So, hier steht schon ein bisschen was über Extensionen.

23:15.310 --> 23:19.650
Wir werden einmal sehen, Extensionen spielen so ähnlich eine Rolle wie

23:19.650 --> 23:22.410
Relation auch was die Anfragesprachen angeht, weil man immer so

23:22.410 --> 23:23.410
Einstiegspunkte braucht.

23:24.530 --> 23:26.910
Oder Root-Objekte, wie wir die früher genannt haben.

23:27.930 --> 23:32.990
Und außerdem kann ich zum Beispiel alle Instanzen eines Objektyps

23:32.990 --> 23:36.790
dadurch erreichen, dass ich so ein Extent dann traversiere.

23:37.110 --> 23:39.730
Allerdings, ich muss nicht ein Extent definieren, ich kann.

23:39.730 --> 23:42.930
Und wenn ich kein definiere, dann habe ich allerdings große Probleme,

23:43.010 --> 23:44.730
die alle zu traversieren und aufzufinden.

23:50.720 --> 23:52.880
So, jetzt geht es los mit den Operatoren.

23:54.600 --> 23:57.120
Bei den Operatoren, da beißt es sich ganz gewaltig.

23:57.660 --> 24:01.060
Denn wir aus der Datenbank-Welt kommen und sagen, wir wollen immer

24:01.060 --> 24:01.980
Polymorph arbeiten.

24:02.320 --> 24:05.660
Der Grundsatz ist, dass wir uns lösen von der spezifischen Mini-Welt,

24:06.440 --> 24:09.700
dass wir also eben, weil es sich um so entsetzlich teure Biester

24:09.700 --> 24:14.720
handelt, dass wir die für möglichst viele Einsatzgebiete unverändert

24:14.720 --> 24:15.700
vorhalten wollen.

24:16.140 --> 24:18.100
Und das geht nur, indem wir generisch vorgehen.

24:18.240 --> 24:20.780
Also wollen wir Polymorphe-Operatoren haben.

24:20.860 --> 24:24.240
Und hier kommt der Trick, der Witz, bei uns ist ja gerade, dass wir

24:24.240 --> 24:24.960
Monomorph sind.

24:25.220 --> 24:30.200
Wir verbinden also die Operatoren mit den Klassen und wissen dann

24:30.200 --> 24:34.140
genau, dass eben auf die Art auch wir gut kapseln können, weil wir an

24:34.140 --> 24:36.380
der Schnittstelle nur die Operatoren zugänglich machen müssen.

24:37.080 --> 24:39.340
Und zweitens ist die Semantik sehr wohl definiert.

24:39.340 --> 24:44.340
Wir schicken eine Nachricht an, eine Ausprägung dieses Objektyps und

24:44.340 --> 24:48.040
dieses Objekt, das versteht dann auch die entsprechenden Nachrichten,

24:48.160 --> 24:49.280
sprich die entsprechenden Operatoren.

24:50.540 --> 24:52.080
So, da beißt es sich als erstes.

24:52.440 --> 24:54.540
Dann werden wir nachher sehen, wie wir da versuchen können

24:54.540 --> 24:55.240
vorbeizukommen.

24:55.340 --> 24:57.180
Ich hatte ja schon gesagt, mit der Vererbung können wir da

24:57.180 --> 24:58.240
möglicherweise was tun.

24:58.600 --> 25:00.920
Das zweite ist natürlich, dass es auch keine Mengenorientierung gibt

25:00.920 --> 25:03.840
in Programmiersprachen und dass wir die auch irgendwie hier noch

25:03.840 --> 25:05.220
unterbringen müssen.

25:05.220 --> 25:08.640
Das macht man, wie wir gesehen haben, eigentlich am elegantesten

25:08.640 --> 25:12.440
dadurch, dass man eine deskriptive Anfragesprache wieder einführt, die

25:12.440 --> 25:14.800
mengenorientiert ist und dann überlässt man irgendeinen Übersetzer

25:14.800 --> 25:18.860
dahinter, dass der das runterbügelt auf eine eher

25:18.860 --> 25:23.400
navigationsorientierte Schnittstelle, wie das die Objektorientierung

25:23.400 --> 25:24.140
darstellt.

25:24.220 --> 25:26.220
Navigation heißt ja einfach, ich habe ein Objekt und dann marschiere

25:26.220 --> 25:30.240
ich irgendwann in entsprechende Referenzketten dann zu den nächsten

25:30.240 --> 25:31.240
weiteren Objekten hin.

25:33.380 --> 25:36.420
So, jetzt haben wir ein nächstes Problem.

25:36.520 --> 25:39.920
Ein Datenbanksystem ist doch dazu da, Daten zu speichern und zu

25:39.920 --> 25:45.000
verwalten und nicht Operatoren irgendwie zu verwalten und eventuell

25:45.000 --> 25:46.640
dann auch noch zu starten und laufen zu lassen.

25:47.660 --> 25:50.100
Das ist nicht die Aufgabe des Datenbanksystems.

25:51.420 --> 25:56.980
Wenn das nicht der Fall ist, dann sollten wir uns in der Tat auch

25:56.980 --> 26:01.420
nicht groß um Operatoren kümmern müssen und die Vorgehensweise im

26:01.420 --> 26:04.300
Datenbankbereich ist in Folge dessen auch, man schweigt sich

26:04.300 --> 26:06.220
eigentlich darüber aus, wo die Operatoren herkommen.

26:06.320 --> 26:09.460
Was man braucht, ist natürlich, wenn man Objekte definiert oder

26:09.460 --> 26:14.680
Objekttypen definiert, dass man angibt, welche Operatoren auf diese

26:14.680 --> 26:16.020
Objekte angewandt werden können.

26:16.260 --> 26:20.140
Also in der üblichen Weise, dass wir eben den Operatorvorrat mit den

26:20.140 --> 26:26.280
Objektdefinitionen verbinden, aber wir wollen offen lassen, wo deren

26:26.280 --> 26:27.300
Implementierung steckt.

26:27.300 --> 26:29.560
Die wird meistens an einer ganz anderen Stelle, es gibt gelegentlich

26:29.560 --> 26:34.180
sowas wie Methodenserver etwa, wo dann die Definitionen oder die

26:34.180 --> 26:39.980
Übersetzten der Objektcode der Operatoren liegt und dann irgendein

26:39.980 --> 26:43.860
System muss sich die Daten rausholen und dann eben entsprechend die

26:43.860 --> 26:47.380
Operatordefinitionen sich beschaffen und dann die auf die Objekte

26:47.380 --> 26:47.760
anwenden.

26:49.460 --> 26:56.640
So, in Folge dessen verlangen wir nur Folgendes, dass wir im Schema,

26:56.800 --> 27:00.940
in dem wir unsere Objekttypen führen, nur die Signaturen angeben

27:00.940 --> 27:02.020
unserer Operatoren.

27:02.520 --> 27:06.000
Und wir sprechen eben dann, wenn wir nur die Signaturen angeben von

27:06.000 --> 27:09.720
Operatoren und die Implementierung wird als Methoden bezeichnet.

27:09.840 --> 27:12.700
Da muss ich mich auch ein bisschen an diese Terminologie gewöhnen.

27:12.800 --> 27:15.640
Sie sind im Allgemeinen gewohnt, bei der Objektorientierung einfach

27:15.640 --> 27:16.960
nur von Methoden zu sprechen.

27:17.400 --> 27:19.740
Wir müssen jetzt eine Unterscheidung treffen.

27:20.400 --> 27:24.340
Die Signatur, sprich die Operatoren, führen wir im Schema mit und das

27:24.340 --> 27:27.640
ist Aufgabe des Datenbanksystems, die zu verwalten.

27:28.040 --> 27:33.760
Aber den Code selbst, das sind die Methoden, der fällt außerhalb des

27:33.760 --> 27:36.140
Verantwortungsbereichs des Datenbanksystems.

27:38.300 --> 27:40.780
Natürlich müssen wir irgendwo sorgen dafür, dass da konsistent ist.

27:40.840 --> 27:43.740
Wenn ich an einer Stelle Operatoren vorgebe, an der Schnittstelle,

27:43.800 --> 27:45.660
dann müssen die irgendwo anders im System zu finden sein.

27:46.980 --> 27:50.500
Und da kann es abenteuerlich werden, nehmen wir an, wir führen unsere

27:50.500 --> 27:52.600
Schema -Definition unter 50 Jahre fort.

27:53.780 --> 27:55.760
Und nach 50 Jahren kommen Sie daher und sagen, jetzt muss ich aber mal

27:55.760 --> 27:58.340
die Operatoren da anwenden auf meine Instanzen.

27:59.080 --> 28:01.360
Dann müssen wir sicher sein, dass nach 50 Jahren auch noch die

28:01.360 --> 28:02.300
Operatoren da sind.

28:03.420 --> 28:05.620
Wahrscheinlich sind die Programmiersprachen, die Sie heute gewohnt

28:05.620 --> 28:10.580
sind, in 50 Jahren gehören die schon lange in der Vergangenheit an.

28:11.140 --> 28:14.100
Oder Sie müssen sich mit so üblen Problemen herumschlagen, wie heute

28:14.100 --> 28:20.100
die Altsysteme, die auf Kobol aufsetzen und kein Mensch ist mehr da,

28:20.160 --> 28:21.100
der überhaupt Kobol versteht.

28:22.120 --> 28:24.000
Also da ist langfristig ein Problem.

28:25.400 --> 28:28.700
Aber unser Datenbanksystem sagt ja nur, die Signatur muss noch

28:28.700 --> 28:29.480
gewährleistet werden.

28:29.560 --> 28:31.700
Und wenn da eine Spezifikation dahinter steckt, die sagt, was die

28:31.700 --> 28:34.180
Semantik dieser Operatoren ist, dann müssen wir sicherstellen, dass

28:34.180 --> 28:40.620
irgendwo eine entsprechende Implementierung dieser Operatoren, also

28:40.620 --> 28:41.940
eine entsprechende Methode vorliegt.

28:41.940 --> 28:45.180
Aber dass die im Laufe der Zeit sich mehrfach geändert haben kann,

28:45.340 --> 28:48.740
weil sie auf andere Programmiersprachen übergewechselt sind, das ist

28:48.740 --> 28:50.340
dem Datenbanksystem leicht gültig.

28:51.020 --> 28:54.180
Aber wir haben ein zusätzliches Konsistenzproblem über lange Zeiten,

28:54.720 --> 28:56.880
das glaube ich noch keiner so ganz richtig versteht.

28:57.020 --> 29:01.020
Also wie schafft man es, dass objektorientierte Datenbasen nach 50

29:01.020 --> 29:05.000
Jahren auch noch zugreifbar sind, während im relationalen Fall, die

29:05.000 --> 29:09.240
wir ja nur Polymorphe-Operatoren haben, die gleich dem Datenbanksystem

29:09.240 --> 29:09.780
zuschlagen.

29:12.580 --> 29:18.020
Das nächste ist natürlich, wenn wir schon über lange Lebensdauer reden

29:18.020 --> 29:21.960
und das nicht darauf verlassen können, dass immer noch die gleiche

29:21.960 --> 29:25.100
Programmiersprachenverwendung findet, dann müssen wir ganz

29:25.100 --> 29:28.220
offensichtlich sogar offen lassen, in welcher Programmiersprache die

29:28.220 --> 29:29.260
Methoden vorliegen.

29:29.640 --> 29:31.440
Und wir müssen im Folgendes etwas anderes tun, wir müssen eine

29:31.440 --> 29:34.700
sogenannte Sprachanbindung schaffen, die sagt, dass wenn ich jetzt ein

29:34.700 --> 29:39.700
Schema vorgebe und damit bestimmte Signaturen vorgebe, wie schaffe ich

29:39.700 --> 29:43.380
es sozusagen jetzt aus dieser neutralen Sprach, neutralen Welt, in der

29:43.380 --> 29:47.020
ich nur den Aufruf produzieren kann, in die entsprechende

29:47.020 --> 29:50.000
Implementierungssprache für die Methoden überzuspringen.

29:50.960 --> 29:53.780
Also müssen wir Sprachanbindungen definieren und die sind tatsächlich

29:53.780 --> 29:54.980
dann auch Teil des Standards.

29:56.240 --> 29:59.540
Also wie verbinde ich, wie springe ich von dieser neutralen

29:59.540 --> 30:02.440
Beschreibung in die konkrete Implementierungssprache über,

30:02.580 --> 30:05.020
beziehungsweise in den Code, der aus der Übersetzung hervorgegangen

30:05.020 --> 30:05.340
ist.

30:06.720 --> 30:08.940
Wenn ich das tue, dann kann ich natürlich sagen, dann ist es sowieso

30:08.940 --> 30:12.480
gleichgültig, in welcher Programmiersprache ich programmiere.

30:12.960 --> 30:16.340
Und es gibt halt Anhänger, die machen alles in C++ und andere, die

30:16.340 --> 30:17.260
machen das alles in Java.

30:18.360 --> 30:20.520
Und da muss ich sagen, als Datenmarktsystem ist es mir egal.

30:21.620 --> 30:24.040
Ich definiere die Sprachanbindung und da kannst du nehmen, was du

30:24.040 --> 30:24.240
willst.

30:27.840 --> 30:30.400
Also, das, was wir noch brauchen, sind Sprachanbindungen.

30:31.220 --> 30:40.880
Aber hier haben wir das Problem der Lebensdauer, auch der Operatoren.

30:46.050 --> 30:48.070
Und das ist ein neues System, ein neues Problem.

30:51.990 --> 30:57.890
So, jetzt macht die ODMG nochmal einen Unterschied, der scheint Ihnen

30:57.890 --> 31:00.070
zunächst einmal sehr bekannt zu sein.

31:00.550 --> 31:02.790
Es wird nämlich unterschieden zwischen Schnittstellen und Klassen.

31:03.620 --> 31:06.070
Die Schnittstelle ist echte Kapselung.

31:06.290 --> 31:11.050
Das Einzige, was Sie da zu sehen kriegen, sind die Operatoren.

31:11.610 --> 31:16.010
Und Sie können auf ein bestimmtes Objekt nur zugreifen über die

31:16.010 --> 31:18.750
Operatoren, die für seinen Typ definiert sind.

31:19.230 --> 31:20.410
Na, das stimmt nicht ganz.

31:20.790 --> 31:25.030
Wenn man Attribute sichtbar machen will, dann kann man zusätzlich in

31:25.030 --> 31:27.890
einer Schnittstelle auch noch Attributdefinition unterbringen.

31:28.050 --> 31:30.930
Also gewisse Teile der Struktur sichtbar machen.

31:31.850 --> 31:35.470
Aber die Puristen sagen an der Stelle, ne, das ist auch nicht der

31:35.470 --> 31:39.630
Fall, sondern für jedes Attribut, das ich sichtbar mache, sehe ich

31:39.630 --> 31:41.470
eine Lese- und eine Schreiboperation vor.

31:41.550 --> 31:43.030
Dann gibt es überhaupt nur Operatoren.

31:44.250 --> 31:46.690
Hier in der ODMG wird also impliziert, wenn ich eine

31:46.690 --> 31:50.650
Attributdefinition angebe, dann ist damit impliziert, dass ich sowohl

31:50.650 --> 31:51.970
eine Lese- als eine Schreiboperation habe.

31:52.890 --> 31:57.250
Oder ich interpretiere die Verwendung des Attributs als eine Lese-

31:57.250 --> 31:58.890
oder Schreiboperation, je nach Kontext.

32:00.390 --> 32:04.150
Also wir definieren Schnittstellen und hinter den Schnittstellen

32:04.150 --> 32:06.910
verbirgt sich im Wesentlichen einfach die Operatorin.

32:07.850 --> 32:11.730
Also es gibt zu Schnittstellen gar keine Implementierung

32:11.730 --> 32:13.350
offensichtlich, denn wir wissen zu wenig.

32:14.390 --> 32:18.650
Wenn wir über Implementierung sprechen, dann sprechen wir, das ist

32:18.650 --> 32:20.170
auch zunächst mal vertraut, über Klassen.

32:21.210 --> 32:24.410
Eine Klasse impliziert also, dass es eine Implementierung gibt.

32:25.470 --> 32:28.930
Aber da wir ja jetzt Klassen im Schema definieren, haben wir ein

32:28.930 --> 32:29.290
Problem.

32:29.430 --> 32:31.730
Denn wir haben ja gesagt, die Implementierung, um die wollen wir uns

32:31.730 --> 32:32.930
ja im Datenbanksystem gar nicht kümmern.

32:33.670 --> 32:35.210
Was steht denn dann in einer Klasse drin?

32:35.990 --> 32:41.570
In einer Klasse steht im Wesentlichen all das drin, was derjenige, der

32:41.570 --> 32:45.970
die Operatorin als Methoden zu implementieren hat, wissen muss.

32:47.070 --> 32:49.210
Also das hat eigentlich nichts mit der Verwendung zu tun, man

32:49.210 --> 32:52.310
entscheidet jetzt zwischen denen, die Klassen verwenden, die brauchen

32:52.310 --> 32:56.290
nur die Schnittstelle und denjenigen, denen die Aufgabe übertragen

32:56.290 --> 33:01.150
wird, die Schnittstellen in Form von Klassen zu implementieren.

33:01.510 --> 33:05.130
Und denen muss ich wenigstens sagen, außer der Semantik der

33:05.130 --> 33:09.330
Operatoren, die ich meine, muss ich insbesondere die Struktur meiner

33:09.330 --> 33:12.030
Objekte mitgeben, denn die braucht er für die Implementierung.

33:13.470 --> 33:20.330
Klassen enthalten also im Wesentlichen so viel an Information, dass

33:20.330 --> 33:23.130
eine Implementierung möglich ist.

33:23.630 --> 33:27.650
Also sie schaffen die Voraussetzung, Implementierung zu schaffen.

33:28.430 --> 33:30.530
Aber, und sie unterstellen letzten Endes auch, dass dann

33:30.530 --> 33:33.570
Implementierungen für die Operatoren existieren, dass man tatsächlich

33:33.570 --> 33:37.090
die Operatoren, wenn man sie aufruft, auch in ihrer Implementierung

33:37.090 --> 33:39.150
vorliegen, also ausgeführt werden können.

33:39.150 --> 33:44.930
Aber sie sagen selbst nichts zur Implementierung.

33:45.130 --> 33:48.490
Die Implementierung ist unverändert nicht Teil des Schemas.

33:50.010 --> 33:56.430
So, auf der Seite vermerkt, SQL 99 hat auch inzwischen Elemente der

33:56.430 --> 33:58.550
Objektorientierung und da wird dagegen verstoßen.

33:58.670 --> 34:01.370
Da wird im Schema auch die Implementierung mit angegeben.

34:02.170 --> 34:06.150
Da sieht man, dass zum Beispiel zwei Entwicklungen völlig nebenläufig

34:06.150 --> 34:09.330
abgegangen sind, die beiden offenbar wenig miteinander gesprochen

34:09.330 --> 34:13.830
haben und plötzlich kriegen sie zwei Definitionen, die ganz

34:13.830 --> 34:16.310
offensichtlich von ihrer Philosophie weit auseinander klaffen.

34:17.430 --> 34:19.590
Das passiert aber nicht nur im Datenbankbereich, sondern auch an

34:19.590 --> 34:20.150
anderen Stellen.

34:20.850 --> 34:26.290
Aber man muss also immer höllisch aufpassen, dass man gewisse

34:26.290 --> 34:29.910
Grundregeln keineswegs in allen Standards wiederfindet, selbst wenn

34:29.910 --> 34:32.750
sie das ähnliche zu tun vorgeben, sondern dass sie häufig auseinander

34:32.750 --> 34:33.090
klaffen.

34:33.910 --> 34:39.270
Wir hier bleiben hart, Implementierungen haben nichts im Schema zu

34:39.270 --> 34:39.530
suchen.

34:41.230 --> 34:45.050
Und infolgedessen ist auch eine Klasse, sagt nichts über die

34:45.050 --> 34:48.590
Implementierung aus, aber sie gibt genügend Informationen mit, damit

34:48.590 --> 34:50.850
eine Implementierung der Methoden erfolgen kann.

34:52.350 --> 34:56.370
Jetzt sehen wir auch prompt, dass wir zu Schnittstellen überhaupt

34:56.370 --> 34:57.730
keine Instanzen definieren können.

34:57.730 --> 35:01.330
Da ist zu wenig da, um Implementierungen definieren zu können, sondern

35:01.330 --> 35:04.610
wir wissen nur, dass irgendwo, wenn wir die Schnittstelle verwenden,

35:04.750 --> 35:06.590
dass da eine Implementierung existiert.

35:07.450 --> 35:11.710
Bei Klassen hingegen, zu Klassen, da kennen wir die Struktur, also

35:11.710 --> 35:13.990
können wir auch dazu Instanzen erzeugen.

35:14.090 --> 35:16.250
Denn im Datenbanksystem wird ja nur die Struktur abgelegt.

35:16.970 --> 35:19.090
Also brauchen wir eine volle Beschreibung der Struktur, haben wir ja

35:19.090 --> 35:22.010
gesehen, die Voraussetzung für die Implementierung ist auch, wie wir

35:22.010 --> 35:25.170
jetzt sehen, Voraussetzung dafür, dass ich überhaupt Objekte erzeugen

35:25.170 --> 35:26.590
kann, die ich in der Datenbase ablehnen kann.

35:26.590 --> 35:32.510
Ich kann also nur Instanzen erzeugen, oder Objekte erzeugen, zu

35:32.510 --> 35:34.070
Klassen, nicht zu Schnittstellen.

35:34.490 --> 35:36.910
Aber das ändert nicht daran, dass ich natürlich irgendwo, wenn mich

35:36.910 --> 35:40.270
nur Schnittstellen interessieren und ich keine Daten, keine Objekte

35:40.270 --> 35:42.730
erzeuge, dann gibt es nicht den größten Grund, warum ich mir über

35:42.730 --> 35:43.730
Klassen Bescheid wissen soll.

35:43.790 --> 35:46.210
Dann reichen mir wirklich schon allein die Schnittstellen.

35:48.510 --> 35:53.010
Diese Trennung, die ist in Java auch geläufig, wird also, wie Sie

35:53.010 --> 35:56.010
sehen, im Datenbankbereich etwas anders ausgelegt.

35:56.010 --> 36:01.290
Und zwar sehr strikt, um die Methoden für die Implementierung zu

36:01.290 --> 36:03.210
trennen von der Datenbasis.

36:03.230 --> 36:05.770
Denn die Datenbasis hat nur mit Zuständen zu tun, sie verwaltet nur

36:05.770 --> 36:06.310
Zustände.

36:12.580 --> 36:17.160
So, hier sieht man mal sowas, wie das aussehen kann.

36:19.080 --> 36:22.680
Im Grunde genommen haben wir auch zwei Vererbungsmechanismen, nämlich

36:22.680 --> 36:26.800
eine Vererbung Implements, die sind auch geläufig.

36:28.180 --> 36:31.000
Implements heißt nichts anderes, als ich definiere eine Klasse und

36:31.000 --> 36:33.200
diese Klasse implementiert eine Schnittstelle.

36:33.320 --> 36:35.840
Oder sie kann auch mehrere Schnittstellen implementieren.

36:36.080 --> 36:40.540
Hier sehen Sie zum Beispiel als eine Möglichkeit, wir führen eine

36:40.540 --> 36:42.860
Interface, eine Schnittstelle ITicket ein.

36:43.940 --> 36:49.240
Und ITicket hat einfach nur zwei Operatoren, nämlich Buche und

36:49.240 --> 36:49.760
Storniere.

36:51.800 --> 36:54.420
Die kann man auch schön hinschreiben und sagen, ich erwarte dann, dass

36:54.420 --> 36:55.060
das passiert.

36:56.820 --> 37:02.480
Aber wir kümmern uns gar nicht darum, wie die Objekte selbst, die das

37:02.480 --> 37:04.940
Ticket implementieren, wie die aussehen.

37:05.260 --> 37:08.060
Und wir kümmern uns vor allem auch nicht um die Implementierung von

37:08.060 --> 37:09.920
Buche und Storniere selbst.

37:10.100 --> 37:16.020
Aber dann kommen wir anschließend zu einer Klasse Ticket, von der wir

37:16.020 --> 37:18.620
sagen, die soll jetzt das ITicket implementieren.

37:19.560 --> 37:28.080
Und da geben wir an der Stelle die Ahnung, wie ein Ticket-Objekt

37:28.080 --> 37:29.040
aufgebaut ist.

37:29.140 --> 37:34.660
Nämlich es besteht aus zwei Attributen, Ticket nur und Inhaber.

37:35.920 --> 37:41.120
Und nimmt noch Bezug darauf, dass Inhaber auf ein Objekt verweist, vom

37:41.120 --> 37:44.420
Typ Kunde, also dass da eine Referenzsemantik untergebracht wird.

37:44.820 --> 37:45.620
Und das ist es schon.

37:47.380 --> 37:49.840
Denn die Operatoren, brauchen Sie sich nochmal hinzuschreiben, die

37:49.840 --> 37:50.340
kennen Sie ja.

37:50.440 --> 37:56.840
Über Implements wird ja gesagt, welche Operatoren geerbt werden.

37:57.980 --> 38:01.080
Also können wir uns davon ausgehen, wenn ich die Klasse Ticket nehme,

38:01.180 --> 38:03.100
dass ich auch mir diese Operatoren wieder zur Verfügung stehe.

38:03.200 --> 38:06.660
Gott sei Dank als Methode, aber die Implementierung selbst, wie

38:06.660 --> 38:07.560
gesagt, kriegen wir nicht zu sehen.

38:07.560 --> 38:11.740
Wir schaffen nur die Voraussetzung dafür, dass wir implementieren

38:11.740 --> 38:16.520
können, wie ein Objekt vom Typ Ticket aufgebaut ist.

38:18.760 --> 38:21.800
Also das ist, wenn Sie wollen, einfacher als das, was Sie gewohnt

38:21.800 --> 38:22.060
sind.

38:25.040 --> 38:28.040
Die zweite Art der Vererbung...

38:29.720 --> 38:34.500
Wenn wir Implementierung vererben, dann werden alle Implementierungen

38:34.500 --> 38:35.780
übernommen.

38:37.860 --> 38:41.180
Und natürlich können wir übrigens auch noch im Implement selbst

38:41.180 --> 38:45.040
wiederum, wir können Vererbungen zwischen Schnittstellen definieren.

38:50.020 --> 38:53.100
Und Schnittstellen können also jederzeit vererbt werden.

38:53.260 --> 38:57.100
Also das Implement kann ich auch wiederum auf weitere Schnittstellen

38:57.100 --> 38:57.700
übernehmen.

38:58.500 --> 39:02.020
Aber dann gibt es noch eine weitere Art der Vererbung, das ist das

39:02.020 --> 39:02.620
Extents.

39:03.020 --> 39:07.240
Und das Extents, das ist nur zwischen zwei Klassen möglich.

39:08.640 --> 39:11.800
Und dann sage ich eben, wenn ich zum Beispiel Ticket habe, und jetzt

39:11.800 --> 39:15.860
gibt es irgendwelche Spezial-Tickets, Sie wissen ja alle, Sie fliegen

39:15.860 --> 39:18.360
ja wahrscheinlich auch eher, wenn immer möglich, billig.

39:18.600 --> 39:21.040
Also Wochenende dazwischen oder Last Minute.

39:21.580 --> 39:24.500
Alles natürlich dann sehr eingeschränkt, Sie können nicht ohne

39:24.500 --> 39:25.320
weiteres stornieren.

39:25.680 --> 39:28.560
Und da kann man sich vorstellen, dafür führen wir jetzt eine Klasse

39:28.560 --> 39:30.200
Special -Ticket ein.

39:30.200 --> 39:34.600
Und Special-Ticket erweitert einfach Ticket.

39:35.240 --> 39:38.100
Und die Erweiterung ist an dieser Stelle im Wesentlichen dadurch

39:38.100 --> 39:39.900
gegeben, dass wir Strukturen einführen.

39:40.380 --> 39:42.440
Oder Sie auch noch zusätzlich Operatoren einführen.

39:45.500 --> 39:49.720
So, dann gilt auch ansonsten alles, was wir aus Java gewohnt sind.

39:49.860 --> 39:52.500
Nämlich Schnittstellen zwischen Schnittstellen.

40:29.060 --> 40:33.240
Also die Aussage, die gemacht wird von der Seite des Datenbanksystems,

40:33.300 --> 40:33.940
ist die folgende.

40:34.820 --> 40:38.220
Wir unterstellen, dass es Operatoren, Buche und Storniere gibt.

40:38.580 --> 40:39.880
Das haben wir mit der Schnittstelle festgelegt.

40:41.600 --> 40:45.680
Und wir sagen, wie der Aufruf erfolgt, also wie die Signatur aussieht.

40:46.360 --> 40:47.840
Über die Implementierung sagen wir nichts aus.

40:47.840 --> 40:53.880
Wenn wir jetzt übergehen zu einer Klasse, dann führen wir dort die

40:53.880 --> 40:56.180
Struktur des Objektes ein.

40:56.260 --> 40:58.900
Wir sagen an dieser Stelle, es gibt zwei Attribute, nicht mehr.

41:00.440 --> 41:03.980
Es gibt genau diese zwei Attribute und die sind die erzeugten.

41:03.980 --> 41:06.580
Wenn ich ein Objekt erzeuge, dann sind die zwei Attribute der

41:06.580 --> 41:09.120
Datenbasis zu finden, also die Belegungen dieser Attribute.

41:09.580 --> 41:12.260
Und die kann derjenige, der die Methoden implementiert, darauf kann er

41:12.260 --> 41:12.720
sich verlassen.

41:12.840 --> 41:13.280
Die hat er.

41:14.500 --> 41:18.140
Ansonsten machen wir wieder keinerlei Aussage darüber, wie die

41:18.140 --> 41:19.200
Implementierung aussieht.

41:20.040 --> 41:23.640
Wenn wir jetzt schlecht spezifizieren und völlig vage sagen, was

41:23.640 --> 41:26.000
eigentlich Buche tun soll, dann dürfen wir uns nicht beschweren, wenn

41:26.000 --> 41:28.620
hinterher da irgendeine idiotische Implementierung fabriziert wird.

41:29.680 --> 41:34.240
Also wir machen wirklich nur minimale Aussagen, nämlich nur für die

41:34.240 --> 41:38.420
Implementierung sagen wir dir, wie die Struktur des Objektes aussieht.

41:41.660 --> 41:42.060
Nö.

41:44.300 --> 41:48.240
Ich als Handwerker sage, das ist ein softwaretechnisches Problem,

41:48.380 --> 41:50.080
schreiben Sie Ihre Spezifikation hin entsprechend.

41:51.140 --> 41:54.380
Schreiben Sie es formal hin oder schreiben Sie ein Handbuch oder

41:54.380 --> 41:56.100
schreiben Sie sonst irgendwie eine Spezifikation.

41:56.700 --> 41:59.240
Wenn Sie mich dann aber sagen, das ist zu wenig, dann sage ich, naja,

41:59.380 --> 42:01.520
es gibt ja Datenwörterbücher, die stelle ich Ihnen wieder zur

42:01.520 --> 42:03.320
Verfügung, schreiben Sie Ihre Spezifikation rein.

42:03.660 --> 42:07.940
Also ich nehme hier an der Stelle schon eine sehr drastische und

42:07.940 --> 42:08.820
einfache Haltung ein.

42:08.820 --> 42:11.880
Ich sage, das Implementieren der Methoden ist ein softwaretechnisches

42:11.880 --> 42:12.240
Problem.

42:13.660 --> 42:16.100
Mein einziges softwaretechnisches Problem ist das Datenbanksystem,

42:16.320 --> 42:18.380
aber nicht das, was an Methoden darum umgeschrieben wird.

42:19.620 --> 42:21.140
Und das ist die Haltung, die hier eingenommen wird.

42:21.720 --> 42:25.840
Natürlich würde ich von Ihnen erwarten, dass Sie ein bisschen weiter

42:25.840 --> 42:28.120
denken, als nur das Datenbankproblem sehen.

42:28.200 --> 42:31.420
Dass Sie tatsächlich auch dafür Sorge tragen, auf irgendeine Weise,

42:31.640 --> 42:34.500
dass Buchung, das was Sie mit Buche meinen, auch eindeutig

42:34.500 --> 42:35.320
festgehalten ist.

42:35.860 --> 42:37.840
Aber das ist eine Frage der Spezifikation.

42:40.020 --> 42:43.120
Ich lehne mich dann zurück und sage, naja, das hat der Kollege Tichy

42:43.120 --> 42:45.460
Ihnen ja beigebracht, da brauche ich mich nicht mehr darum zu kümmern.

42:48.560 --> 42:52.220
Aber wenn Ihnen die Antwort unbefriedigend ist, sie sagt tatsächlich,

42:52.320 --> 42:54.100
wo die Verantwortung getrennt sind.

42:55.160 --> 42:57.800
Ich übernehme nicht die Verantwortung dafür, dass Sie eine saubere

42:57.800 --> 42:59.000
Spezifikation hinschreiben.

42:59.000 --> 43:01.720
Ich übernehme nur die Verantwortung dafür, dass wenn Sie mir eine

43:01.720 --> 43:04.580
Signatur hinschreiben, dass ich dafür Sorge trage, dass die am Ende

43:04.580 --> 43:06.260
auch umgesetzt wird.

43:06.740 --> 43:08.480
Oder umgesetzt worden ist, noch genauer.

43:09.460 --> 43:13.360
Aber ob richtig oder nicht, dafür übernehme ich keine Garantie.

43:18.190 --> 43:22.890
Aber ich gebe zu, natürlich aus Systemssicht haben Sie völlig recht.

43:23.370 --> 43:24.450
Sie müssen beides betrachten.

43:28.360 --> 43:30.700
So, jetzt kann ich dabei Extensionen haben.

43:30.840 --> 43:33.540
Als Extents können wir uns ansehen, was können wir mit Extents noch

43:33.540 --> 43:34.020
anfangen.

43:34.600 --> 43:37.720
Und jetzt ist ja die Probleme der Datenbanktechnik sind ja nicht

43:37.720 --> 43:40.020
plötzlich deshalb verschwunden, weil ich jetzt von Relationen auf

43:40.020 --> 43:41.400
Objektorientierung übergewechselt bin.

43:41.720 --> 43:44.720
Ich habe ja immer noch das Problem, dass ich gigantische Zahlen von

43:44.720 --> 43:46.020
Objekten da rumsitzen habe.

43:46.940 --> 43:48.460
Objektidentifikatoren kann ich noch nicht mal selber vergeben.

43:48.800 --> 43:51.040
Die werden irgendwo im System vergeben, da werden mir nur irgendwelche

43:51.040 --> 43:51.800
Garantien gegeben.

43:51.800 --> 43:57.760
Aber um da irgendwas zu finden, um irgendwie zuzugreifen, um das

43:57.760 --> 44:01.180
Skalierbarkeitsproblem zu lösen, muss ich im Grunde genommen wieder

44:01.180 --> 44:03.240
aus dem Sachproblem herauskommen.

44:03.340 --> 44:05.680
Und das Sachproblem ist durch Werte dargestellt und nicht durch

44:05.680 --> 44:09.400
irgendwelche generierten Identifikatoren, von denen ich weiß, wie sie

44:09.400 --> 44:09.860
aussehen.

44:10.360 --> 44:12.920
Also wollen wir doch unverändert Schlüssel haben.

44:13.060 --> 44:15.680
Das Primitivste, was ich brauche in einem Datenbanksystem, um etwas zu

44:15.680 --> 44:16.380
finden, ist ein Schlüssel.

44:17.560 --> 44:23.020
Und ein Schlüssel, hier seht ihr schon die modifizierte Definition,

44:24.160 --> 44:26.000
weil da ja das letzte Mal Einwände gekommen sind.

44:26.660 --> 44:31.060
Der Schlüssel, den definiere ich jetzt wie im relationalen Bereich.

44:31.260 --> 44:35.520
Ich greife gewisse Attribute heraus oder Attributkombinationen und

44:35.520 --> 44:40.480
sage wiederum, die Werte unter dieser Attributkombination, die sind

44:40.480 --> 44:44.660
eindeutig, und jetzt sind sie eindeutig nicht datenbasisweit, sondern,

44:44.800 --> 44:48.560
wie im relationalen Fall auch, nur noch begrenzt auf die Menge der

44:48.560 --> 44:49.920
Objektypen, also auf den Extent.

44:50.580 --> 44:54.800
Der Extent ist also einer, in dem ich Werte-Eindeutigkeit definieren

44:54.800 --> 44:55.140
kann.

44:56.300 --> 44:59.600
Also Schlüssel, der Schlüssel-Definition-Einführer.

44:59.720 --> 45:02.220
Und hier ist nichts anderes ausgesagt, als dass natürlich wiederum

45:02.220 --> 45:04.760
eine Kombination von Werten als Schlüssel dienen kann.

45:06.280 --> 45:09.360
Also wertbasierten Zugriff brauchen Sie im Datenbankbereich, da führt

45:09.360 --> 45:09.960
nichts dran vorbei.

45:11.420 --> 45:14.900
Und wir sorgen wiederum dafür, an dieser Stelle, dass wir ihn für

45:14.900 --> 45:18.340
eindeutige Erkennung verwenden können, aber ansonsten werden wir

45:18.340 --> 45:20.880
natürlich auch wieder Selektionsausdrücke zulassen, die irgendwie

45:20.880 --> 45:22.240
beliebige Werte abfragen.

45:24.260 --> 45:27.280
So, jetzt kann man sich natürlich fragen, also hier sehen Sie gerade

45:27.280 --> 45:27.960
noch eine Definition.

45:28.300 --> 45:32.160
Ticket habe ich als Klasse eingeführt, eigentlich, genauer genommen,

45:32.200 --> 45:33.740
hätte ich noch ein Extent daraus machen müssen.

45:34.620 --> 45:39.920
Und hier steht halt da, dass wir hier jetzt von den beiden Attributen

45:39.920 --> 45:42.520
hier die Ticketnummer zum Schlüssel erklären.

45:43.520 --> 45:46.340
Die Definition ist dann, wie Sie sehen, ganz ähnlich, wie im

45:46.340 --> 45:47.140
relationalen Fall.

45:49.640 --> 45:52.520
So, der Schlüssel kann sich ändern.

45:52.760 --> 45:56.480
Jedermann kann reingehen und, wenn Sie das nicht irgendwie getrennt

45:56.480 --> 45:58.660
verbieten könnten, die Ticketnummer abändern.

45:58.660 --> 46:02.040
Das Einzige, was wir dann wieder von Datenbankseite aus garantieren,

46:02.160 --> 46:04.880
ist, dass, wenn abgeändert wird, dass nicht plötzlich Duplikate

46:04.880 --> 46:07.740
erscheinen, sondern dass weiterhin die Eindeutigkeit dieser Werte

46:07.740 --> 46:08.880
garantiert ist.

46:09.060 --> 46:10.200
Aber der Schlüssel kann sich ändern.

46:10.660 --> 46:13.840
Aber jetzt sehen wir, dass wir an der Stelle doch mächtiger sind als

46:13.840 --> 46:14.800
der relationale Fall.

46:14.920 --> 46:17.680
Dort ist der Schlüssel das einzige Mittel, um überhaupt eindeutig zu

46:17.680 --> 46:20.760
identifizieren, während wir hier immer unseren Objektidentifikator

46:20.760 --> 46:21.000
haben.

46:21.100 --> 46:24.720
Solange wir an dem Objektidentifikator für ein Objekt festhalten,

46:24.880 --> 46:26.620
können wir die Werte beliebig ändern.

46:27.340 --> 46:30.560
Und das Objekt als solches bleibt unverändert erkennbar.

46:31.440 --> 46:32.740
Allerdings nicht mehr über seine Werte.

46:36.930 --> 46:39.910
So, das Zweite ist referenzielle Konsistenz.

46:39.970 --> 46:41.190
Das wollen wir doch auch nicht aufgeben.

46:41.550 --> 46:45.230
Das haben wir doch eingeführt, weil wir gesagt haben, irgendwie sind

46:45.230 --> 46:48.450
ja diese Relationen, oder jetzt unsere Extensionen beispielsweise,

46:48.550 --> 46:51.870
unsere Objektwelten, auch nicht getrennt voneinander, sondern da gibt

46:51.870 --> 46:52.990
es weiterhin Querbezüge.

46:53.350 --> 46:56.610
Und die Querbezüge haben wir ja über referenzielle Konsistenzen

46:56.610 --> 46:57.190
eingeführt.

46:57.810 --> 47:03.150
Jetzt ist es aber so, dass wir im objektorientierten Bereich uns

47:03.150 --> 47:04.830
eigentlich auf die Werte nicht mehr verlassen können.

47:04.990 --> 47:07.350
Also sowas wie eine Fremdschlüsselbedingung, das zieht nicht so

47:07.350 --> 47:07.670
richtig.

47:08.210 --> 47:10.350
Weil erstmal kann ich mich gar nicht darauf verlassen, dass es

47:10.350 --> 47:13.390
Schlüssel gibt, während ich das im relationalen Fall ja unbedingt tun

47:13.390 --> 47:13.750
konnte.

47:15.310 --> 47:18.850
Das Einzige, was also wieder unverändert ist, ist der

47:18.850 --> 47:19.910
Objektidentifikator.

47:19.910 --> 47:22.390
Also werden jetzt die referenziellen Konsistenzen im

47:22.390 --> 47:25.090
objektorientierten Bereich wieder zurückgeführt auf

47:25.090 --> 47:26.750
Objektidentifikator.

47:27.230 --> 47:28.930
Das geschieht folgendermaßen.

47:29.430 --> 47:33.290
Ich führe ein Konstrukt ein, ein sogenanntes Relationship-Konstrukt.

47:34.710 --> 47:38.250
Und das definiere ich einfach über zwei Objekttypen.

47:40.370 --> 47:44.490
Und das besagt im Wesentlichen, im einen Objekttyp finde ich ein

47:44.490 --> 47:50.410
Attribut, das Attribut verweist auf einen anderen Objekttyp.

47:50.490 --> 47:53.550
Und jetzt verlasse ich mich darauf, dass in dem zweiten Objekttyp,

47:53.590 --> 47:55.410
dass da ein Objekt existiert, auf das ich verweise.

47:56.650 --> 48:00.910
Und dass insbesondere immer dieser Verweis aufrechterhalten wird.

48:00.970 --> 48:02.710
Dass also nicht plötzlich da ein ungültiger Wert steht.

48:03.830 --> 48:07.190
Und um das, wir werden das gleich sehen, um das sicherstellen zu

48:07.190 --> 48:10.850
können, da ja im objektorientierten Bereich immer Verweise nur in eine

48:10.850 --> 48:14.150
Richtung führen, führe ich im zweiten Objekttyp einen Rückwärtsverweis

48:14.150 --> 48:14.430
ein.

48:14.430 --> 48:17.050
Und dazu dient dieses Relationship-Konstrukt.

48:17.730 --> 48:22.590
Das besagt also einfach, ich verweise in die eine rein, um die

48:22.590 --> 48:25.570
Garantien abzugeben, die wir sonst mit Fremdschlüsselbedingungen, wie

48:25.570 --> 48:30.930
diesem On-Cascade oder On-Delete, noch verfolgt haben im Schema.

48:31.270 --> 48:35.270
Das setze ich jetzt hier durch, indem ich einen Rückwärtsverweis

48:35.270 --> 48:35.790
erzwinge.

48:37.130 --> 48:40.610
Wir werden dann noch ansehen, wie das in der Tatendefinitionssprache

48:40.610 --> 48:41.790
erfolgt.

48:41.790 --> 48:45.450
Und zwar im Wesentlichen, um den Rückwärtsverweis heranzubauen, sage

48:45.450 --> 48:48.310
ich gleich was an der anderen Stelle, wo der Rückwärtsverweis steht,

48:48.390 --> 48:49.650
über ein Inverse-Konstrukt.

48:50.890 --> 48:53.230
Also während die Schlüsselbedingungen, sagen wir mal, sehr ähnlich

48:53.230 --> 48:57.110
sind in dem relationalen Fall, ist die referenzielle Konsistenz anders

48:57.110 --> 48:58.870
aufgebaut im objektorientierten Bereich.

48:59.210 --> 49:02.190
Wir basieren auf Objektidentifikatoren und nicht auf Werten,

49:02.250 --> 49:04.910
insbesondere nicht auf Schlüsseln, weil Schlüssel sozusagen eine

49:04.910 --> 49:07.950
freiwillige Leistung im objektorientierten Fall ist, also nicht

49:07.950 --> 49:10.530
unbedingt vorhanden sein muss.

49:10.530 --> 49:15.210
Was wir aber auf jeden Fall als garantiert vorliegend ansehen können,

49:15.490 --> 49:16.690
ist immer der Objektidentifikator.

49:16.790 --> 49:19.990
Also führen wir jetzt die Querbezüge zwischen verschiedenen Klassen

49:19.990 --> 49:22.990
wieder auf die Objektidentifikatoren zurück.

49:23.510 --> 49:26.270
Also haben wir dann bei Objekttyp immer irgendwie eigentlich den

49:26.270 --> 49:27.790
Objektidentifikator vorzustellen.

49:28.130 --> 49:28.810
Hier steht zum Beispiel.

49:31.290 --> 49:38.010
Wir nehmen wieder unser Ticket und jetzt drehen wir den Spieß aber

49:38.010 --> 49:38.510
etwas um.

49:38.510 --> 49:40.750
Sie erinnern sich, vorher waren zwei Attribute.

49:41.990 --> 49:47.610
Und das eine Attribut, hier habe ich ins Klassen genommen, aber an

49:47.610 --> 49:50.250
sich würde eine Schnittstelle an dieser Stelle auch reichen.

49:52.030 --> 49:57.790
Hier war ursprünglich ein zweites Attribut hinter dem Ticket, nämlich

49:57.790 --> 49:58.150
Kunde.

49:58.950 --> 50:03.350
Und Kunde ist ja ein Verweis auf ein Objekt eines anderen Typs.

50:03.350 --> 50:07.010
Und jetzt sagen wir an dieser Stelle nicht mehr, da kann ein Verweis

50:07.010 --> 50:09.670
stehen und ansonsten machen wir keine Aussagen über den Verweis.

50:09.810 --> 50:13.430
Und jetzt sagen wir plötzlich, der Verweis, der da steht, der kann ich

50:13.430 --> 50:14.230
ins Leere führen.

50:14.430 --> 50:17.210
Da muss ein existierender Kunde dahinter stecken.

50:18.770 --> 50:23.390
Wenn wir das machen, dann sagen wir nicht mehr einfach Kunde, Inhaber,

50:23.430 --> 50:25.650
sondern sagen wir, das ist eine Relationship.

50:28.430 --> 50:31.670
Das heißt, ich verweise etwas anderes rein, was existieren muss.

50:32.470 --> 50:35.490
Und außerdem sage ich gleich noch, ja, wie sieht es denn bei dem

50:35.490 --> 50:36.190
anderen aus?

50:39.410 --> 50:47.830
Nämlich, der hat dann seinerseits ein Attribut Ticket und das verweist

50:47.830 --> 50:48.670
zurück auf mich.

50:50.490 --> 50:52.850
Oder da finde ich zumindest einen Verweis auf mich zurück.

50:53.390 --> 50:56.970
Das heißt, wir bauen jetzt eine zirkuläre Verweiskette auf zu einem

50:56.970 --> 50:58.730
zweiten Objekt und von dort wieder zurück.

50:59.370 --> 51:01.650
So, und jetzt kann es natürlich sein, dass es andere Mengenwerte gibt,

51:01.710 --> 51:02.970
dann sieht es ein bisschen anders aus.

51:03.810 --> 51:06.170
Zum Beispiel haben wir hier auch so etwas, wir haben jetzt noch

51:06.170 --> 51:06.730
erweitert.

51:07.470 --> 51:10.010
Jetzt haben wir mehr mit Ticket gemacht, wir haben nämlich noch ein

51:10.010 --> 51:12.550
weiteres Attribut Buchungen eingeführt.

51:13.890 --> 51:19.650
Und wir sagen, wir wollen, das soll angeben, welche Buchungen zu

51:19.650 --> 51:20.750
diesem Ticket gehören.

51:20.750 --> 51:25.110
Und wir erinnern uns, wir haben ja nur noch Direktflüge, also wenn wir

51:25.110 --> 51:31.890
ein Ticket lösen und wir fliegen beispielsweise von Baden Airport

51:31.890 --> 51:38.390
nach, meinetwegen, Galveston in Texas, dann können Sie sich

51:38.390 --> 51:40.650
vorstellen, neben einem langen Flug, den wir inzwischen drin haben,

51:40.710 --> 51:43.770
haben wir noch mehrere kleinere Flüge, alle auf der gleichen

51:43.770 --> 51:44.290
Ticketnummer.

51:45.350 --> 51:50.010
Und infolgedessen hat dieses Ticket mehrere Buchungen und dann sagen

51:50.010 --> 51:53.610
wir, das ist eben eine Menge von Buchungen, auf die dieses Ticket

51:53.610 --> 51:54.130
verweist.

51:54.730 --> 51:58.890
Also führen wir ein Set-Konstrukt ein und sagen im Übrigen, dass das

51:58.890 --> 52:02.970
ein Set ist, der auf Objekte, also Referenzen besitzt, die auf

52:02.970 --> 52:05.110
Buchungen verweisen, auf Objekte von Typ Buchung.

52:05.110 --> 52:08.230
Und jetzt sagen wir, aber auch da wollen wir eine referenzielle

52:08.230 --> 52:09.150
Konsistenz haben, d.h.

52:09.230 --> 52:12.630
wir wollen sicherstehen, wenn da auf irgendein Buch verwiesen wird,

52:12.690 --> 52:13.190
dass es die gibt.

52:14.310 --> 52:14.730
Und dazu,

52:17.950 --> 52:22.370
daher Relationship und dann haben wir ja wieder den Rückwärtsverweis

52:22.370 --> 52:22.950
zu konstruieren.

52:22.950 --> 52:25.830
Dann können wir sagen, also wenn du zu Buchungen kommst, dann gibt es

52:25.830 --> 52:36.410
da auch ein Attribut Ticket und dieses Ticket, dieses Attribut, und

52:36.410 --> 52:39.950
dem steht wieder drin, zu welchem Ticket die spezielle Buchung gehört.

52:40.090 --> 52:42.030
Die ist jetzt wieder offenbar eine Elementik.

52:43.090 --> 52:46.410
Jetzt bauen wir also da so richtig querverweise auf, das ist eine

52:46.410 --> 52:48.830
Möglichkeit, referenzielle Konsistenzen aufzubauen.

52:49.250 --> 52:52.890
Und referenzielle Konsistenzen sind eben ein wichtiges Mittel, um

52:52.890 --> 52:54.690
Konsistenz durchzusetzen.

52:54.850 --> 52:58.030
Also wir sehen, wir bauen uns wieder hier Konsistenzbedingungen auch

52:58.030 --> 53:00.250
im Bereich der objektorientierten Systeme ein.

53:05.290 --> 53:09.010
Das nächste Problem ist jetzt, wir wollen ja Polymorphie haben, habe

53:09.010 --> 53:09.370
ich gesagt.

53:09.370 --> 53:13.090
Und ich hatte auch schon angedeutet, naja, die Vererbung leistet das

53:13.090 --> 53:13.530
eigentlich.

53:14.010 --> 53:19.990
Wir haben also jetzt ein Datenmodell, das Monomorph ist und eine

53:19.990 --> 53:22.510
Aufgabe, die Polymorph definiert ist.

53:22.890 --> 53:25.110
Und jetzt, wie kommen wir von dem einen zum anderen?

53:29.290 --> 53:34.090
Nun, es gibt in der Tat zunächst einmal ein paar eingebaute

53:34.090 --> 53:36.890
Monomorphie -Operatoren, um die brauchen wir uns jetzt nicht groß zu

53:36.890 --> 53:40.930
kümmern, die besagen im Wesentlichen, dass wir natürlich arithmetische

53:40.930 --> 53:44.370
Operatoren auf unseren arithmetischen Datentypen vornehmen können,

53:44.490 --> 53:48.870
dass wir Zeichenketten-Operatoren haben auf Zeichenkettenförmigen

53:48.870 --> 53:53.050
atomaren Typen und auf Referenzen haben wir auch noch die

53:53.050 --> 53:57.330
Dereferenzierung als eine Operation.

53:57.990 --> 54:02.290
Also die sind einfach implizit im Modell mit drin als Monomorphie

54:02.290 --> 54:02.710
-Operatoren.

54:02.710 --> 54:05.750
Aber die interessieren uns ja weniger, sondern interessieren uns ja

54:05.750 --> 54:10.350
vor allem die Operatoren, die auf Objekten arbeiten und da wären wir

54:10.350 --> 54:14.930
eben gerne Polymorph, aus den üblichen Gründen, die zur Polymorphie

54:14.930 --> 54:16.530
bei Datenbanksystemen führt.

54:18.550 --> 54:21.770
So, dann, und ich hatte auch schon angedeutet, die Substituierbarkeit

54:21.770 --> 54:23.690
spielt hier eine wesentliche Rolle.

54:25.510 --> 54:28.890
So, das allererste, was wir brauchen überhaupt, wir müssen erzeugen

54:28.890 --> 54:29.510
können Objekte.

54:31.430 --> 54:35.570
Und das kennen Sie mal als New- oder Create-Operator.

54:36.550 --> 54:40.230
Und wir führen hier etwas Spezifisches ein, nämlich die sogenannte

54:40.230 --> 54:41.250
Object Factory.

54:42.150 --> 54:45.730
Und diese Object Factory, da gehört tatsächlich ein Polymorpher

54:45.730 --> 54:47.050
-Operator an,

54:51.890 --> 54:52.850
Nämlich der...

54:53.430 --> 54:55.850
Ich muss mir gerade überlegen, warum habe ich hier...

55:02.770 --> 55:06.230
Was ist denn das überhaupt für ein Ding?

55:12.970 --> 55:17.270
Ich vermute, dass ich da mal bei der Vorbereitung der Folien...

55:17.270 --> 55:20.410
Ich habe nämlich ziemlich viel hin- und hergeschoben, dass ich da

55:20.410 --> 55:21.550
irgendeinen Unsinn gemacht habe.

55:21.550 --> 55:25.030
Denn eigentlich, was tut denn ein In an dieser Stelle?

55:25.150 --> 55:26.250
Erzeugt er noch ein neues Objekt?

55:27.870 --> 55:31.290
Ich schaue da mal nach, da erscheint mir sehr dubios an dieser Stelle.

55:31.630 --> 55:37.670
Aber was ich sicherlich brauche, ist ein Object New, nämlich es wird

55:37.670 --> 55:40.470
ein neues Objekt erzeugt.

55:40.890 --> 55:44.910
Und Object, da haben Sie Variable vorzustellen, der dann eben der Wert

55:44.910 --> 55:46.070
entsprechend zugewiesen wird.

55:46.190 --> 55:49.150
Wir gehen also in die Object Factory und die erzeugt ein neues Objekt.

55:51.270 --> 55:52.070
So...

55:53.210 --> 55:56.110
Ah, da muss ich nochmal nachsehen, ob ich da nicht einen Fehler

55:56.110 --> 55:56.770
begangen habe.

56:00.470 --> 56:03.450
So, jetzt werden wir folgendes machen.

56:03.750 --> 56:12.210
Jede Schnittstelle, die wir überhaupt einführen, erbt von Object

56:12.210 --> 56:12.670
Factory.

56:13.390 --> 56:16.930
Und damit haben wir zunächst mal sichergestellt, dass ich von jedem

56:16.930 --> 56:19.670
Typ, kann ich ein Objekt erzeugen.

56:22.490 --> 56:26.610
Aber in Object New ist eine Schnittstelle.

56:27.590 --> 56:29.270
Also da ist keine Implementierung dahinter.

56:29.850 --> 56:34.050
Wenn Sie also eine Klasse einführen und die erbt also jetzt unseren

56:34.050 --> 56:39.970
New Operator, dann müssen Sie dort auch die Implementierung

56:39.970 --> 56:41.190
unterbringen für Ihr New.

56:42.750 --> 56:44.970
Erst dort muss ich zum ersten Mal auf die Klasse stoßen.

56:45.610 --> 56:48.050
Da gilt, jetzt muss das New implementiert werden.

56:48.710 --> 56:52.030
Jetzt wird man versuchen, möglichst weit oben in so einer Hierarchie

56:52.030 --> 56:55.610
dieses New unterzubringen, um dann bei der Implementierung auf

56:55.610 --> 56:57.250
möglichst viele Klassen übertragen zu können.

56:59.170 --> 57:02.270
Aber man darf also nicht vergessen, da ist es nur eine Schnittstelle,

57:02.390 --> 57:07.930
man muss es auf jeden Fall erstmal irgendwann da unten implementieren.

57:11.690 --> 57:15.810
So, und ansonsten wollen wir jetzt eigentlich Folgendes erreichen.

57:15.950 --> 57:21.730
Wir wollen für diese Operationen hier, also im Wesentlichen Set, Bag

57:21.730 --> 57:24.450
und List, da wollen wir eigentlich polymorph sein.

57:25.310 --> 57:28.350
Ist ja auch klar, wenn ich eine Menge von irgendwelchen Objekten

57:28.350 --> 57:31.190
erzeuge, ist es doch ziemlich belanglos, wie die aufgebaut sind.

57:31.630 --> 57:35.650
Menge ist Menge, wir verbinden ja immer die gleiche Semantik damit.

57:35.650 --> 57:41.210
Also wäre es eigentlich sinnvoll, wir würden möglichst weit oben, in

57:41.210 --> 57:44.910
irgendeiner Typ-Hierarchie, die Operatoren für Set, Bag und List

57:44.910 --> 57:45.730
ansiedeln.

57:46.230 --> 57:48.870
Und wir würden sogar gerne auch die Implementierung, also die

57:48.870 --> 57:52.070
Methoden, auch nicht zu weit runterschieben müssen, sodass jeder, der

57:52.070 --> 58:00.090
sich eine Monomorph-Liste einführt, dass der erst nochmal die ganzen

58:00.090 --> 58:01.410
Operationen implementieren muss.

58:01.550 --> 58:04.010
Sondern auch das würde man möglichst gerne weit oben tun.

58:04.010 --> 58:07.070
Aber zunächst mal brauchen wir die polymorphen Operatoren und die

58:07.070 --> 58:11.710
können zunächst mal auch noch durchaus in der Schnittstelle stecken.

58:12.330 --> 58:18.030
Wie gehen wir jetzt vor in der ODMG?

58:19.330 --> 58:24.970
ODMG setzt zunächst mal an die Spitze unserer Typ-Hierarchie eine

58:24.970 --> 58:26.350
Schnittstelle OBJECT.

58:27.430 --> 58:28.610
Und OBJECT kann nicht viel.

58:28.610 --> 58:33.110
Aber OBJECT hat immerhin schon mal drei Eigenschaften und drei

58:33.110 --> 58:33.790
Operationen.

58:33.870 --> 58:35.750
Nämlich, ich kann vergleichen, same as.

58:36.710 --> 58:37.770
Ich kann Objekte kopieren.

58:38.710 --> 58:41.750
Das ist offenbar auch etwas, was für jedes Objekt gelten muss.

58:42.070 --> 58:43.630
Und ich kann Objekte löschen.

58:43.970 --> 58:45.390
Ich kann sie nur nicht neu erzeugen.

58:45.670 --> 58:48.930
Deshalb muss OBJECT Factory separat außerhalb dieser Hierarchie

58:48.930 --> 58:49.750
angesiedelt werden.

58:49.970 --> 58:53.730
Deswegen brauche ich zwingend mehrfach Vererbung an der Stelle, um

58:53.730 --> 58:56.730
sowohl die Eigenschaften OBJECT als auch die von OBJECT Factory zu

58:56.730 --> 58:56.990
erben.

58:57.990 --> 58:59.710
Aber die führe ich irgendwo mal zusammen.

59:00.110 --> 59:02.430
Und dann hoffe ich, muss ich mich um OBJECT Factory nicht mehr

59:02.430 --> 59:02.750
kümmern.

59:04.990 --> 59:11.690
Und jetzt schlägt ODMG bestimmte Schnittstellen vor und sagt, die

59:11.690 --> 59:15.330
sollte man implementieren, um die Polymorphie zu erreichen.

59:16.490 --> 59:23.350
Und man kann ja sagen, dass BACK, SET und LIST alle irgendwie doch

59:23.350 --> 59:25.850
sehr verwandt sind, weil sie zumindest mal einen gewissen

59:25.850 --> 59:26.910
Mengencharakter haben.

59:27.130 --> 59:30.490
Auch wenn im einen Fall mehrfach Mengen zugelassen sind und im anderen

59:30.490 --> 59:33.050
Fall Ordnungen aufgeprägt werden können.

59:33.430 --> 59:35.950
Aber zumindest gewisse Elemente müssen ja gemeinsam sein, weil sie

59:35.950 --> 59:37.870
alle mit dynamischen Mengen umgehen.

59:38.550 --> 59:41.930
Und die dynamische Menge wird dann einfach als eine Schnittstelle

59:41.930 --> 59:44.950
namens COLLECTION definiert.

59:45.350 --> 59:46.870
Und dann sehen wir schon, was wir haben.

59:46.930 --> 59:50.630
Wir können die Menge, also die Kardinalität bestimmen.

59:51.110 --> 59:53.750
Wir können prüfen, ob die Menge leer ist.

59:53.750 --> 59:57.850
Wir können prüfen, ob sie sortiert oder geordnet ist.

59:58.270 --> 01:00:02.670
Wir können nachprüfen, ob ein Element in dieser Menge enthalten ist,

01:00:02.690 --> 01:00:03.290
also Epsilon.

01:00:04.070 --> 01:00:07.950
Wir können ein Element einfügen in die Menge.

01:00:09.430 --> 01:00:13.010
Wenn Sie zum Beispiel einen NEW-Operator anwenden, dann haben Sie zwar

01:00:13.010 --> 01:00:15.170
ein neues Objekt, aber noch lange nicht in irgendeiner Menge stehen.

01:00:15.870 --> 01:00:16.910
Das können wir also einfügen.

01:00:17.450 --> 01:00:20.530
Wir können das Element aus der Menge entfernen.

01:00:20.530 --> 01:00:22.590
Und wir können noch etwas weiteres tun.

01:00:23.330 --> 01:00:26.970
Und das erinnert jetzt stark an unser eingebändetes SQL.

01:00:27.470 --> 01:00:32.070
Wir können auch durch die Menge durchlaufen, die Elemente der Reihe

01:00:32.070 --> 01:00:32.970
nach aufgreifen.

01:00:33.330 --> 01:00:36.010
Und das tun wir, indem wir einen sogenannten Iterator definieren, also

01:00:36.010 --> 01:00:36.990
ein eigenständiges Objekt.

01:00:37.370 --> 01:00:41.190
Und diesen Iterator werden wir dann anschließend anwenden, so ähnlich

01:00:41.190 --> 01:00:48.170
wie diesen Cursor vorher, auf die Elemente dieser Collection.

01:00:49.010 --> 01:00:51.450
Natürlich ist der unterschiedlich definiert.

01:00:51.990 --> 01:00:55.770
Wenn ich nur eine Menge habe, ungeordnet, dann muss ich dafür Sorge

01:00:55.770 --> 01:00:57.650
tragen, dass kein Element zweimal aufgegriffen wird.

01:00:57.770 --> 01:00:59.930
Aber ansonsten kann ich mir die Reihenfolge beliebig auswählen.

01:01:00.410 --> 01:01:03.570
Wenn es eine Liste ist, dann muss ich darauf achten, dass die Ordnung,

01:01:03.730 --> 01:01:06.430
die in der Liste zugrunde gelegt wird, auch eingehalten wird.

01:01:06.530 --> 01:01:09.990
Also insofern unterschiedliche Implementierungen.

01:01:10.370 --> 01:01:13.050
Aber aus Schnittstellensicht brauche ich nur etwas, was mir alle

01:01:13.050 --> 01:01:14.390
Elemente der Reihe nach aufgreift.

01:01:15.310 --> 01:01:16.630
Also da erzeuge ich noch einen Iterator.

01:01:17.610 --> 01:01:20.110
So, das ist natürlich jetzt noch sehr allgemein.

01:01:20.450 --> 01:01:24.410
Und jetzt kann ich zum Beispiel sagen, die Menge ist ein Spezialfall

01:01:24.410 --> 01:01:25.410
unserer Collection.

01:01:25.810 --> 01:01:28.950
Also Set ist, der Doppelpunkt soll jetzt wieder heißen, dass das

01:01:28.950 --> 01:01:30.310
Implements ist.

01:01:31.590 --> 01:01:36.010
Der Set führt jetzt noch Folgendes hinzu.

01:01:36.010 --> 01:01:42.710
Der sagt, jetzt kann ich noch gewisse Dinge einführen, die ich Mengen

01:01:42.710 --> 01:01:43.490
unterstellen kann.

01:01:43.570 --> 01:01:46.270
Nämlich kann ich Mengenoperationen einführen.

01:01:47.310 --> 01:01:50.590
Create Union, Create Intersection, Create Difference.

01:01:51.730 --> 01:01:54.730
Also Vereinigung, Schnittbildung und Differenzbildung.

01:01:55.150 --> 01:01:57.810
Und ich kann außerdem noch auf Teilmengen prüfen.

01:01:58.950 --> 01:02:01.130
Möglicherweise fallen mir noch ein paar andere Dinge ein.

01:02:01.130 --> 01:02:04.970
Ich könnte insbesondere jetzt mal Folgendes sagen, ich will mal in die

01:02:04.970 --> 01:02:06.090
Relationale Welt rein.

01:02:06.210 --> 01:02:08.790
Oder ich will so Dinge übernehmen, die aus der Relationalen Welt

01:02:08.790 --> 01:02:09.090
stammen.

01:02:09.230 --> 01:02:11.790
So eine natürliche Join, eine natürliche Verbindung, das wäre

01:02:11.790 --> 01:02:12.490
eigentlich auch etwas Schönes.

01:02:13.230 --> 01:02:17.630
Dann könnte ich ja auch irgendwie noch eine weitere Relation,

01:02:18.050 --> 01:02:20.510
Doppelpunkt Collection zum Beispiel, einführen.

01:02:20.750 --> 01:02:22.150
Und dann würde die Relation jetzt zum Beispiel eine

01:02:22.150 --> 01:02:24.610
Verbindungsoperation, Selektion und solche Dinge enthalten.

01:02:25.130 --> 01:02:27.370
Also das können wir jetzt eigentlich aufbauen, das wird nicht

01:02:27.370 --> 01:02:28.510
standardmäßig vorgegeben.

01:02:29.370 --> 01:02:33.790
Ich muss aber dazusagen, dass man später auch für die

01:02:33.790 --> 01:02:37.550
Objektorientierung eine sogenannte Objektalgebra eingeführt hat, die

01:02:37.550 --> 01:02:40.210
im Wesentlichen eine Erweiterung der Relationalen Algebra ist.

01:02:40.610 --> 01:02:44.770
Die ist aber nie implementiert worden als kommerziellen Produkten.

01:02:45.610 --> 01:02:48.110
Aber da kann man sich zum Beispiel diese Algebra nehmen und dann eben

01:02:48.110 --> 01:02:54.990
so ein Typ oder jetzt Objektmengen erzeugen, die tatsächlich diese

01:02:54.990 --> 01:02:56.030
Algebra implementieren.

01:02:56.650 --> 01:02:58.090
Also die Mittel wären da.

01:03:01.600 --> 01:03:04.660
So ähnlich kann ich das natürlich dann auch für Listen und für Bags

01:03:04.660 --> 01:03:04.940
machen.

01:03:05.420 --> 01:03:08.240
Und die werden auch tatsächlich im Rahmen der ODMG auch mit als

01:03:08.240 --> 01:03:09.780
Standard Schnittstellen definiert.

01:03:10.780 --> 01:03:13.600
Jetzt schauen wir noch hier drin, wie der Iterator aussieht.

01:03:13.900 --> 01:03:16.160
Der Iterator ist auch noch eine Schnittstelle, muss immer noch

01:03:16.160 --> 01:03:17.560
anschließend implementiert werden.

01:03:18.580 --> 01:03:19.800
Was wollen wir denn da wissen?

01:03:19.940 --> 01:03:22.920
Zum Beispiel wollen wir wissen, sind wir am Ende angelangt.

01:03:25.180 --> 01:03:28.940
Ich muss also mal prüfen, ob ich noch ein Element aufgreifen kann oder

01:03:28.940 --> 01:03:30.780
ob das Ende erreicht ist.

01:03:31.320 --> 01:03:35.160
Dann kann ich den Iterator auch wieder zurücksetzen.

01:03:35.240 --> 01:03:37.160
Dann fange ich wieder am Anfang an, kann auch so wiederholt

01:03:37.160 --> 01:03:37.760
durchlaufen.

01:03:39.480 --> 01:03:43.900
Dann, wenn ich an einer bestimmten Stelle bin, kann ich das dortige

01:03:43.900 --> 01:03:45.060
Element mir beschaffen.

01:03:46.280 --> 01:03:49.720
Dann kann ich das dortige Element auch ersetzen.

01:03:50.900 --> 01:03:54.620
Oder ich kann eins fortschalten, das ist dann dieses Next Position.

01:03:57.300 --> 01:04:02.500
Und der Iterator wird dynamisch angelegt, das heißt er läuft halt

01:04:02.500 --> 01:04:02.920
durch.

01:04:13.510 --> 01:04:16.170
Und wenn irgendwelche Änderungen erfolgen und ich laufe noch ein

01:04:16.170 --> 01:04:18.470
zweites Mal durch, dann kann ich auch diese Änderungen gleich sehen.

01:04:19.010 --> 01:04:20.250
Das ist manchmal auch misslich.

01:04:20.250 --> 01:04:23.610
Dann kann man einen sogenannten stabilen Iterator einführen, der

01:04:23.610 --> 01:04:27.550
besagt dann folgendes, die Änderungen, die ich durchführe, werden

01:04:27.550 --> 01:04:31.790
während des Umgangs mit der Menge nicht sichtbar, sondern werden erst

01:04:31.790 --> 01:04:32.930
am engen Ende abgelegt.

01:04:33.030 --> 01:04:35.910
Das klingt so ein bisschen wie Transaktionen, die ich schon erwähnt

01:04:35.910 --> 01:04:36.170
habe.

01:04:37.990 --> 01:04:40.790
Aber wesentlich bedeutet es einfach, ich kann da auch beliebig ändern

01:04:40.790 --> 01:04:43.290
und normalerweise werden die Änderungen auch sofort sichtbar.

01:04:44.390 --> 01:04:46.370
Wem werde ich durch die Menge durchlaufen?

01:04:50.670 --> 01:04:55.050
So, jetzt habe ich allerdings überhaupt noch nichts dazu gesagt, wie

01:04:55.050 --> 01:05:00.030
denn eigentlich nun so eine objektorientierte Datenbasis auch

01:05:00.030 --> 01:05:01.190
dauerhaft wird.

01:05:02.230 --> 01:05:04.690
Oder auch Robustheit hat man ja auch gesehen, da hat man

01:05:04.690 --> 01:05:08.510
Transaktionsprozeduren im relationalen Fall und es wird sich die Frage

01:05:08.510 --> 01:05:12.090
erheben, kriegen wir das auch in der objektorientierten Welt hin oder

01:05:12.090 --> 01:05:12.390
nicht.

01:05:13.310 --> 01:05:20.570
Jetzt muss man sagen, da wir beim relationalen System immer streng

01:05:20.570 --> 01:05:23.490
trennen zwischen der Datenbankseite und der Seite der

01:05:23.490 --> 01:05:30.550
Anwendungsprogramme, ist wohl definiert in der relationalen Welt, was

01:05:30.550 --> 01:05:35.450
Dauerhaftigkeit bedeutet, zu unterstellen, was immer getan wird, jede

01:05:35.450 --> 01:05:38.890
Relation ist per se dauerhaft und damit auch alle Tupels sind

01:05:38.890 --> 01:05:39.350
dauerhaft.

01:05:40.290 --> 01:05:43.430
Aber in der Objektorientierung, wo wir plötzlich eine sehr viel engere

01:05:43.430 --> 01:05:46.550
Kopplung mit der Programmiersprache haben, da ist natürlich denkbar,

01:05:46.650 --> 01:05:49.830
dass nicht jedes Objekt, das wir erzeugen und das wir nur temporär

01:05:49.830 --> 01:05:53.750
brauchen, gleich per ständig macht, also dauerhaft gemacht wird und

01:05:53.750 --> 01:05:56.090
eine Datenbasis landet.

01:05:56.290 --> 01:06:00.550
Also müssen wir hier in dem Fall der Objektorientierung doch eine

01:06:00.550 --> 01:06:07.270
bessere Trennung vornehmen zwischen dem, was wir als dauerhaft und

01:06:07.270 --> 01:06:09.810
das, was wir als nicht dauerhaft, als Transient ansehen.

01:06:10.830 --> 01:06:14.570
Und jetzt ist die Frage, wie stelle ich das denn an?

01:06:14.870 --> 01:06:18.610
Also ich könnte Folgendes tun, ich könnte sagen, wenn ich nichts

01:06:18.610 --> 01:06:21.090
anderes sage, ist alles dauerhaft.

01:06:22.110 --> 01:06:24.390
Dann müsste jeder Objekt sagen, das wir irgendwie zwischendrin

01:06:24.390 --> 01:06:27.810
erzeugen, das darf aber nicht dauerhaft sein, das ist nur Transient,

01:06:27.970 --> 01:06:30.690
das ist also nur während der Lebensdauer des Programmlaufs definiert.

01:06:31.690 --> 01:06:36.150
Oder, was Programmiersprachanleute weiter, Sympathische finden, es ist

01:06:36.150 --> 01:06:36.910
alles Transient.

01:06:37.870 --> 01:06:41.110
Und ich muss schon ausdrücklich sagen, wenn etwas Persistent sein

01:06:41.110 --> 01:06:44.110
soll, also dauerhaft in der Datenbasis abgelegt werden soll.

01:06:46.490 --> 01:06:53.330
Bei der ODMG sind die Eigenschaften, also die

01:06:53.330 --> 01:06:57.950
Orthogonaltypdefinitionen sagen überhaupt nichts über Dauerhaftigkeit

01:06:57.950 --> 01:06:58.370
aus.

01:06:58.370 --> 01:07:02.610
Ich muss also über die Lebensdauer ausdrücklich etwas sagen, und zwar

01:07:02.610 --> 01:07:05.550
sage ich über die Dauerhaftigkeit an dieser Stelle dann ausdrücklich

01:07:05.550 --> 01:07:05.890
etwas.

01:07:06.070 --> 01:07:09.150
Aber manchmal explizit oder auch implizit.

01:07:10.690 --> 01:07:15.970
So, wir müssen auch die Entscheidung über die Dauerhaftigkeit für

01:07:15.970 --> 01:07:17.570
jedes Objekt einzeln treffen.

01:07:18.050 --> 01:07:21.430
Das ist nicht in allen objektorientierten Datenbanksystemen so

01:07:21.430 --> 01:07:21.970
gewesen.

01:07:22.590 --> 01:07:25.270
Und manche, die sich nicht ganz an den Standort halten, da tun das

01:07:25.270 --> 01:07:25.770
auch anders.

01:07:25.770 --> 01:07:29.650
Manche mal gehen folgendermaßen vor, die sagen, ich definiere für

01:07:29.650 --> 01:07:32.290
einen Typ, ob er dauerhaft ist oder nicht.

01:07:32.990 --> 01:07:36.030
Und jedes Objekt dieses Typs ist dann, wenn es erzeugt wird,

01:07:36.130 --> 01:07:39.330
automatisch entweder nicht dauerhaft oder automatisch dauerhaft.

01:07:39.930 --> 01:07:42.930
Bei ODMG wird gesagt, nein, wir binden das nicht an den Typ, es ist

01:07:42.930 --> 01:07:46.750
also völlig orthogonal zu den Typeigenschaften.

01:07:47.170 --> 01:07:51.170
Und infolgedessen muss ich für jedes Objekt sagen, ob es dauerhaft

01:07:51.170 --> 01:07:52.430
sein soll oder nicht.

01:07:52.430 --> 01:07:56.330
Und jetzt schwindelt sich auch ODMG so ein bisschen drumherum und

01:07:56.330 --> 01:07:58.530
sagt, überlassen wir mal der Sprachanbindung, wie die das tatsächlich

01:07:58.530 --> 01:07:59.250
leisten will.

01:08:00.670 --> 01:08:03.550
Und hier habe ich als ein Beispiel etwas das folgende.

01:08:05.030 --> 01:08:10.950
Wenn ich C++ nehme, der C++ Sprachanbindung, dort wird eine spezielle

01:08:10.950 --> 01:08:16.870
Form des New Operators verwendet, die besagt, in der ich dann sagen

01:08:16.870 --> 01:08:21.030
muss, ist das Persistent oder nicht, ist das Objekt dauerhaft oder

01:08:21.030 --> 01:08:21.330
nicht.

01:08:22.470 --> 01:08:29.670
Bei Java, da wird etwas anderes gemacht, da unterstelle ich ja immer

01:08:29.670 --> 01:08:35.210
noch, dass ich irgendwie meinen Heap habe, also einen Speicher, über

01:08:35.210 --> 01:08:37.790
den ich mit Garbage Collection drüber laufe, und da wird einfach

01:08:37.790 --> 01:08:38.750
folgendes gesagt.

01:08:38.750 --> 01:08:47.570
Wenn ich von definierten Startobjekten aus, die dauerhaft sind, alle

01:08:47.570 --> 01:08:51.130
Objekte, die ich von dort erreiche, sind per Definition auch

01:08:51.130 --> 01:08:51.730
dauerhaft.

01:08:52.650 --> 01:08:56.390
Das heißt, da wird es gebunden an die Eigenschaft, ob ich von

01:08:56.390 --> 01:08:59.850
dauerhaften Objekten aus diese Objekte erreichen kann.

01:09:00.270 --> 01:09:02.230
Und die werden also aus der Garbage Collection sozusagen ausgenommen.

01:09:03.710 --> 01:09:06.930
Die Objekte, die nicht von solchen dauerhaften Objekten erreichbar

01:09:06.930 --> 01:09:12.010
sind, die gelten dann automatisch als nicht dauerhaft und können dann

01:09:12.010 --> 01:09:15.110
auch im Rauf des Programmablaufs, wenn sie überhaupt nicht mehr

01:09:15.110 --> 01:09:16.570
erreichbar sind, wieder beseitigt werden.

01:09:17.390 --> 01:09:20.910
Das hängt also auch etwas mit den unterschiedlichen Philosophien

01:09:20.910 --> 01:09:22.150
hinter den Sprachen zusammen.

01:09:22.250 --> 01:09:24.830
Jetzt sehen Sie, an der Stelle liefert sich das Datenbanksystem, muss

01:09:24.830 --> 01:09:26.670
es auch, der Sprachanbindung aus.

01:09:26.670 --> 01:09:31.250
Es kann diese Entscheidung nicht eigenständig treffen, weil das eine

01:09:31.250 --> 01:09:34.210
Eigenschaft ist, die Sie der Sprachdefinition überlassen.

01:09:35.210 --> 01:09:38.230
Das ist in gewisser Weise ärgerlich, weil Sie an der Stelle die

01:09:38.230 --> 01:09:42.870
Dauerhaftigkeit nicht direkt diktieren können und nicht kontrollieren

01:09:42.870 --> 01:09:43.070
können.

01:09:43.190 --> 01:09:46.530
Sie können nur prüfen, ob Dauerhaftigkeit vorliegt oder nicht.

01:09:48.350 --> 01:09:52.730
Aber, um doch Kontrolle zu erreichen, machen wir Folgendes.

01:09:52.850 --> 01:09:57.850
Wir sagen, wenn Extensionen definiert sind, die sind dauerhaft.

01:09:58.010 --> 01:09:59.990
Alles, was in Extensionen liegt, ist dauerhaft.

01:10:00.870 --> 01:10:06.570
Das heißt, wenn wir in einer Definition einer Klasse jetzt sagen, dazu

01:10:06.570 --> 01:10:09.890
existiert ein Extent, dann haben wir damit auch automatisch gesagt,

01:10:10.150 --> 01:10:13.010
alles, was wir da reinstecken, ist auch dauerhaft.

01:10:13.850 --> 01:10:16.530
Da sehen Sie wieder, da wird eine gewisse Ähnlichkeit zu den

01:10:16.530 --> 01:10:17.790
Relationen hin erzeugt.

01:10:18.050 --> 01:10:20.070
Und wir müssen uns Folgendes nur mit dem Rest rumschlagen, nämlich

01:10:20.070 --> 01:10:22.890
denjenigen Objekten, die nicht in Extensionen reingeraten.

01:10:27.950 --> 01:10:30.530
Aber wir können, also wie gesagt, wir wollen es ja nicht

01:10:30.530 --> 01:10:32.190
ausschließlich Extensionen ausliefern.

01:10:32.790 --> 01:10:36.110
Beispielsweise ist ja denkbar, dass manche Klassen es gar nicht

01:10:36.110 --> 01:10:41.430
verdienen, Extensionen zu werden, weil andere Gründe dazu führen, dass

01:10:41.430 --> 01:10:42.650
wir die nicht voll ausnützen können.

01:10:42.650 --> 01:10:44.190
Wir wollen keine Schlüsseldefinition etwa.

01:10:44.830 --> 01:10:47.450
Und wir wollen vielleicht auch nicht alle Objekte dauerhaft machen.

01:10:47.890 --> 01:10:50.250
Dann ist laut der Devise, da müssen wir irgendwie zumindest die

01:10:50.250 --> 01:10:51.990
Erreichbarkeit sicherstellen.

01:10:52.390 --> 01:10:54.310
Zumindest wenn wir als Sprachanbindung Java verwenden.

01:10:54.930 --> 01:10:57.310
Und das geschieht folgendermaßen.

01:10:59.070 --> 01:11:06.630
Wir führen in einer weiteren Schnittstelle, Datenbasis, Database,

01:11:07.170 --> 01:11:13.450
führen wir die Möglichkeit ein, Objekte zu benennen.

01:11:13.930 --> 01:11:17.070
Wenn man will, mit dauerhaften Variablen zu belegen.

01:11:18.310 --> 01:11:20.670
Wir haben ja immer nur die Objektidentifikationen, die wir nie zu

01:11:20.670 --> 01:11:21.190
sehen kriegen.

01:11:21.530 --> 01:11:24.310
Also müssen wir, wenn wir auch wieder Einstiegspunkte definieren

01:11:24.310 --> 01:11:27.210
wollen, müssen wir wohl übel Namen verwenden, die irgendwie aus

01:11:27.210 --> 01:11:28.830
unserer eigenen Anwendungswelt kommen.

01:11:29.250 --> 01:11:32.890
Und das erfolgt über eine sogenannte Bind-Operation.

01:11:32.890 --> 01:11:38.510
Und die Bind-Operation sagt, es gibt irgendein Objekt und dem verpasse

01:11:38.510 --> 01:11:39.350
ich einen Namen.

01:11:40.250 --> 01:11:42.610
Und dieser Name muss jetzt irgendwo im Datenbanksystem auch verwaltet

01:11:42.610 --> 01:11:42.930
werden.

01:11:43.050 --> 01:11:45.630
Das heißt, wenn ich mit dem Namen anrücke, dann wird das zugehörige

01:11:45.630 --> 01:11:47.310
dauerhafte Objekt gefunden.

01:11:47.430 --> 01:11:50.850
Und von dem aus kann ich weiterlaufen und weitere dauerhafte Objekte

01:11:50.850 --> 01:11:51.250
erreichen.

01:11:52.550 --> 01:11:56.210
Und wenn ich also jetzt dieses Binden vorgenommen habe, also im

01:11:56.210 --> 01:11:59.410
Datenbanksystem mitgeteilt habe, dass ich hier ein Wurzelobjekt

01:11:59.410 --> 01:12:02.650
einführe und einen bestimmten Namen, dann kann ich anschließend per

01:12:02.650 --> 01:12:05.730
Look -Up natürlich jetzt mir den zugehörigen Objekt in den

01:12:05.730 --> 01:12:08.810
Identifikator verschaffen, um von dort aus dann loszumarschieren durch

01:12:08.810 --> 01:12:09.230
die Datenbasis.

01:12:09.690 --> 01:12:11.530
Das ist das sogenannte Navigieren.

01:12:11.850 --> 01:12:13.850
Ich marschiere einfach entlang der Verweisketten weiter.

01:12:15.270 --> 01:12:19.110
Und wenn ich das Objekt nicht mehr haben will, dann sage ich Unbind,

01:12:19.590 --> 01:12:20.770
dann verschwindet es aus meiner Welt.

01:12:22.030 --> 01:12:25.810
Und dann ist es offensichtlich, wenn wir jetzt etwa die Java

01:12:25.810 --> 01:12:29.570
-Sprachenbindung nehmen, dann gibt es kein dauerhaftes Objekt mehr,

01:12:29.630 --> 01:12:31.830
über das ich jetzt weitere dauerhafte Objekte erreichen könnte.

01:12:32.010 --> 01:12:35.170
Das heißt, die anderen werden auch aus der Dauerhaftigkeit entlassen

01:12:35.170 --> 01:12:37.110
und werden dann irgendwann eingesammelt.

01:12:37.330 --> 01:12:40.370
Wir sehen übrigens, dass wir jetzt auch die Speicherbereinigung nicht

01:12:40.370 --> 01:12:42.650
nur im Hauptspeicher vornehmen müssen, sondern dass wir jetzt auch im

01:12:42.650 --> 01:12:45.510
Hintergrundspeicher sowas wie eine Speicherbereinigung vorhalten

01:12:45.510 --> 01:12:45.790
müssen.

01:12:50.240 --> 01:12:51.740
So, das habe ich jetzt erklärt.

01:12:53.240 --> 01:12:54.560
Jetzt kommt noch die Robustheit.

01:12:55.680 --> 01:12:57.540
Dazu brauchen wir Transaktionen.

01:12:57.540 --> 01:13:00.360
Nun, wir sind ja in einer objektorientierten Welt und so wie wir den

01:13:00.360 --> 01:13:03.260
Iterator jetzt als eigenes Objekt eingeführt haben, so führen wir halt

01:13:03.260 --> 01:13:05.700
auch Transaktionen als eigene Objekte ein.

01:13:08.220 --> 01:13:11.320
Da steckt also jetzt plötzlich nicht mehr eine Transaktionsprozedur,

01:13:11.440 --> 01:13:15.940
sondern jetzt ist echt das Ausführen von irgendetwas, das wird als ein

01:13:15.940 --> 01:13:17.160
Transaktionsobjekt eingeführt.

01:13:17.240 --> 01:13:19.420
Wir führen als erstes mal überhaupt ein Transaktionsobjekt ein und

01:13:19.420 --> 01:13:22.820
dann müssen wir anschließend sagen, was da durchgeführt werden soll.

01:13:24.600 --> 01:13:30.220
So, wir brauchen wieder eine Transaction Factory, die erzeugt erstmal

01:13:30.220 --> 01:13:38.120
eine neue Transaktion und lässt außerdem noch zu, dass wir auch die

01:13:38.120 --> 01:13:41.440
Augen feststellen können, welche Art Transaktion augenblicklich denn

01:13:41.440 --> 01:13:42.540
läuft.

01:13:44.060 --> 01:13:49.640
So, und dann Transaktionen selbst, Transaktionsobjekte, haben jetzt

01:13:49.640 --> 01:13:52.280
die Operation, die wir uns auch wünschen, nämlich, ich kann die

01:13:52.280 --> 01:13:58.020
Transaktion starten, Beginn Transaction, heißt hier Beginn, ich kann

01:13:58.020 --> 01:14:02.100
abschließend erfolgreich das End of Transaction oder wie wir auch

01:14:02.100 --> 01:14:07.440
gesagt haben, das Commit, die Transaktion übernimmt jetzt die

01:14:07.440 --> 01:14:11.620
Verantwortung für die Persistenz und anschließend das Datenbanksystem

01:14:11.620 --> 01:14:14.720
für die Dauerhaftigkeit oder ich kann sie auch abbrechen, weil ich

01:14:14.720 --> 01:14:18.460
nicht zufrieden bin mit ihr und dann habe ich eine Abort-Operation.

01:14:18.460 --> 01:14:21.180
Also wir haben genau die Operation, die wir auch kennen aus dem

01:14:21.180 --> 01:14:23.440
Transaktionsbereich, die finden wir hier auch vor.

01:14:25.840 --> 01:14:31.540
So, und jetzt gibt es eine Vorschrift, die besagt, wenn du dauerhafte

01:14:31.540 --> 01:14:36.940
Objekte erzeugen willst oder dauerhafte Effekte erzielen willst, dann

01:14:36.940 --> 01:14:40.360
geht das nur innerhalb einer Transaktion.

01:14:41.920 --> 01:14:43.860
Wir sehen also, wir müssen irgendwie dann auch einen

01:14:43.860 --> 01:14:46.860
Transaktionskontext definieren, wenn wir jetzt eine Operation

01:14:46.860 --> 01:14:49.660
durchführen, dann müssen wir sagen, in welchem Transaktionskontext

01:14:49.660 --> 01:14:50.160
laufen die.

01:14:50.680 --> 01:14:53.140
Das habe ich jetzt nicht einzeln aufgeführt, aber hier sehen wir

01:14:53.140 --> 01:14:56.840
deutlich, wir müssen noch zusätzlich für unsere Operationen, die wir

01:14:56.840 --> 01:15:02.240
ausführen auf Objekten, müssen wir, sofern es sich um persistente oder

01:15:02.240 --> 01:15:06.140
dauerhafte Objekte handelt, müssen wir auch den Transaktionskontext

01:15:06.140 --> 01:15:06.580
mitgeben.

01:15:10.870 --> 01:15:14.230
Also wir finden eigentlich alles, was wir aus den relationalen

01:15:14.230 --> 01:15:18.130
Systemen kennengelernt haben, in einer modifizierten Form, auch etwas

01:15:18.130 --> 01:15:23.610
anders und mehr der Objektphilosophie entsprechend, auch in der

01:15:23.610 --> 01:15:24.730
Objektorientierung wieder.

01:15:24.970 --> 01:15:28.190
Das ist schon mal tröstlich und man kann sich auch vorstellen, woher

01:15:28.190 --> 01:15:28.610
das rührt.

01:15:28.870 --> 01:15:32.190
Erst gab es relationale Datenbanken und die Erfahrung, die man damit

01:15:32.190 --> 01:15:35.190
hat und das, was man als Forderung stellt, das wird halt übertragen

01:15:35.190 --> 01:15:36.590
jetzt auch in die objektorientierte Welt.

01:15:36.690 --> 01:15:41.790
Aber wir haben umgekehrt gesehen, dass wir die Monomorphie ein

01:15:41.790 --> 01:15:45.930
bisschen umgehen müssen, dass wir Verantwortungen an unterschiedlichen

01:15:45.930 --> 01:15:48.590
Stellen unterbringen, dass wir insbesondere auch die Implementierungen

01:15:48.590 --> 01:15:52.970
nicht als Teil der Aufgabe des Datenbanksystems, sondern irgendeiner

01:15:52.970 --> 01:15:55.090
anderen Systeme ansehen.

01:15:55.790 --> 01:16:02.110
Es bleibt nur noch eins übrig, dass die Skalierbarkeit unserer

01:16:02.110 --> 01:16:06.970
Datenbasen wird ja auch dadurch erreicht, dass wir mengenorientiert

01:16:06.970 --> 01:16:10.730
denken und dass wir deskriptiv vorgehen.

01:16:10.730 --> 01:16:15.790
Wir wollen also ja in SQL sagen, welche Eigenschaften besitzt unser

01:16:15.790 --> 01:16:19.350
Ergebnis, das beschreiben wir in dem Fall durch einen SQL-Ausdruck und

01:16:19.350 --> 01:16:23.950
dann lassen wir es losgehen, das hat der Optimierer und der übersetzt

01:16:23.950 --> 01:16:27.130
das Ganze schließlich in einen Anfrageplan, der normalerweise die

01:16:27.130 --> 01:16:31.710
relationale Algebra irgendwie nutzt und dann wird das Ergebnis

01:16:31.710 --> 01:16:32.970
produziert und nach außen wiedergegeben.

01:16:33.610 --> 01:16:36.890
Und das hätten wir doch gerne auch bei einer Objektorientierung.

01:16:40.910 --> 01:16:48.670
Also erlaubt ODMG auch objektorientierte Anfragesprachen, das ist die

01:16:48.670 --> 01:16:49.210
OQL.

01:16:49.750 --> 01:16:54.390
Eigentlich besteht sogar diese Sprachdefinition aus mehreren Teilen,

01:16:55.030 --> 01:17:02.790
nämlich einer DDL, das ist die Object Definition Language, die

01:17:02.790 --> 01:17:08.430
interessiert uns auch, ist aber eine reine Datendefinitionssprache,

01:17:09.350 --> 01:17:12.690
sagt also, wie gesagt, nichts darüber aus, wie implementiert wird, das

01:17:12.690 --> 01:17:14.550
muss irgendwo anders geschehen.

01:17:17.430 --> 01:17:19.410
Und dann kommt noch eine OQL.

01:17:20.370 --> 01:17:23.010
Und jetzt ist eigentlich das Betrübliche, deshalb gehe ich da schnell

01:17:23.010 --> 01:17:26.590
durch, weil nämlich der praktische, praktische Bedeutung dieser beiden

01:17:26.590 --> 01:17:30.250
Sprachen ODL und OQL nie sehr weit gereicht hat.

01:17:31.570 --> 01:17:37.170
Bei Objektorientierung ist noch viel stärker als bei relationalen

01:17:37.170 --> 01:17:42.290
Systemen die Annahme, dass eigentlich die Benutzung der Datenbank aus

01:17:42.290 --> 01:17:45.330
Programmen heraus erfolgt, in dem Fall aus objektorientierten

01:17:45.330 --> 01:17:45.850
Programmen.

01:17:46.610 --> 01:17:49.730
Und da macht man folgendes, da nimmt man nämlich eine klassische

01:17:49.730 --> 01:17:56.670
Typdefinition oder Schemadefinition in der Notation der

01:17:56.670 --> 01:18:00.610
Programmiersprache, also C++ oder Java, und baut dann Übersetzer, die

01:18:00.610 --> 01:18:03.830
sich diese Schemadefinition herausnehmen und in eine interne Form im

01:18:03.830 --> 01:18:04.930
Datenbanksystem übersetzen.

01:18:05.270 --> 01:18:08.610
Man geht also gar nicht den Umweg über die ODL und sagt, ich kriege

01:18:08.610 --> 01:18:10.670
das alles eigentlich aus den Anwendungsprogrammen heraus.

01:18:11.750 --> 01:18:17.570
Und bei der OQL, die ist ja nur sinnvoll, wenn wir tatsächlich auch

01:18:17.570 --> 01:18:20.810
mengenorientiert vorgehen.

01:18:20.810 --> 01:18:23.790
Das hat man bei relationalen Systemen auch sehr stark gemacht, denn da

01:18:23.790 --> 01:18:25.130
gibt es ja keine andere Möglichkeit.

01:18:25.290 --> 01:18:27.910
Wir können ja nicht irgendwelche Referenzketten ablaufen.

01:18:28.710 --> 01:18:31.130
Aber in der Objektorientierung, auch in objektorientierten

01:18:31.130 --> 01:18:34.070
Programmiersprachen, spielt ja eigentlich das Verfolgen von Pfaden

01:18:34.070 --> 01:18:34.930
eine große Rolle.

01:18:35.470 --> 01:18:39.790
Also da kommt auch die Mengenorientierung nicht so zum Tragen.

01:18:40.210 --> 01:18:42.930
Also könnte man die OQL gerade noch nehmen, wenn man Spontananfragen

01:18:42.930 --> 01:18:43.270
stellt.

01:18:43.390 --> 01:18:46.830
Und ob man den Aufwand für Spontananfragen wirklich treiben soll, da

01:18:46.830 --> 01:18:50.470
kann man zumindest sehr wohl darüber diskutieren und streiten.

01:18:51.370 --> 01:18:56.170
Erfolg, zwar standardisiert ist die ODL und die OQL, aber ihr

01:18:56.170 --> 01:18:58.030
praktischer Wert ist relativ gering.

01:18:58.190 --> 01:19:02.870
Viele Datenbankhersteller solcher Systeme bieten die gar nicht an.

01:19:03.950 --> 01:19:07.050
Und deshalb kann ich auch relativ schnell durchgehen, weil sie zwar

01:19:07.050 --> 01:19:10.930
vielleicht akademisch interessant ist, aber in der Praxis eben doch

01:19:10.930 --> 01:19:12.110
nicht die Bedeutung erlangt hat.

01:19:12.110 --> 01:19:14.430
Leider muss ich sagen, als Datenbanker fühle ich mich natürlich auch

01:19:14.430 --> 01:19:15.550
sehr wohl mit diesen Sprachen.

01:19:16.410 --> 01:19:20.430
Hier ist die ODL, die kennen wir ja schon im Wesentlichen.

01:19:20.730 --> 01:19:22.810
Wir haben jetzt hier mal den Kunden als Ersten.

01:19:23.530 --> 01:19:27.270
Wir sagen gleichzeitig, da gibt es auch, den wollen wir als Extent

01:19:27.270 --> 01:19:28.570
verwenden.

01:19:28.850 --> 01:19:30.630
Und wir geben dann, weil es ein Extent ist, auch gleich einen

01:19:30.630 --> 01:19:31.190
Schlüssel mit.

01:19:31.550 --> 01:19:33.830
Nämlich den Schlüsselname, der muss jetzt irgendwo auftauchen.

01:19:34.050 --> 01:19:36.190
Der ist auch tatsächlich da, hier als ein Attribut.

01:19:36.790 --> 01:19:39.550
Wir geben also den Namen vor, wir geben das Telefon vor.

01:19:39.550 --> 01:19:43.190
Hier haben wir noch für die Telefonnummer selbst sogar noch eine

01:19:43.190 --> 01:19:44.430
Unterstruktur angegeben.

01:19:44.570 --> 01:19:48.210
Nämlich gesagt, das besteht aus dem Ortskennzeichen und der

01:19:48.210 --> 01:19:49.350
eigentlichen Telefonnummer.

01:19:51.170 --> 01:19:53.170
Und dann sagen wir auch gleich, das hatten wir aber auch schon vorher.

01:19:53.710 --> 01:19:56.830
Dann sagen wir auch gleich, dass wir übrigens auch eine referenzielle

01:19:56.830 --> 01:19:58.250
Konsistenz einführen wollen.

01:19:58.330 --> 01:20:02.590
Nämlich, wir wollen für diesen Kunden auch angeben, welche Tickets er

01:20:02.590 --> 01:20:02.810
hat.

01:20:02.870 --> 01:20:07.030
Und da er ja durchaus mehrere Tickets im Augenblick halten kann, geben

01:20:07.030 --> 01:20:08.430
wir eine Menge von Tickets an.

01:20:08.430 --> 01:20:15.730
Und wir sagen, die referenzielle Konsistenz geht in eine Klasse

01:20:15.730 --> 01:20:16.410
Ticket.

01:20:16.890 --> 01:20:20.490
Und dort finden wir ein Attribut Inhaber, das den Rückwärtsverweis

01:20:20.490 --> 01:20:20.930
enthält.

01:20:22.530 --> 01:20:26.490
So, und dann geben wir noch zwei Operationen hier an, welche wir

01:20:26.490 --> 01:20:26.930
verwenden.

01:20:27.130 --> 01:20:28.670
Ich nehme also hier eine U-Klassen-Definition.

01:20:31.090 --> 01:20:32.830
Jetzt nehmen wir Ticket, muss das ja auftauchen.

01:20:33.610 --> 01:20:37.090
Bei Ticket sagen wir, soll auch ein Extent geschaffen werden.

01:20:37.090 --> 01:20:41.290
Auch gebe ich jetzt ein Schlüssel angeben.

01:20:41.610 --> 01:20:43.890
Schlüssel soll Ticketnummer sein, wir kennen das ja schon.

01:20:44.310 --> 01:20:47.990
Und hier sehen wir auch schon unsere beiden Relationen.

01:20:48.130 --> 01:20:50.850
Was wir insbesondere jetzt betrachten, ist hier, wir hatten vorher

01:20:50.850 --> 01:20:59.410
gesagt, bei Kunde haben wir ja ein Inverse gehabt auf ein Attribut

01:20:59.410 --> 01:21:00.090
Inhaber.

01:21:00.170 --> 01:21:03.250
Jetzt finden wir hier dieses Attribut Inhaber.

01:21:03.250 --> 01:21:06.830
Und gemäß unserer Definition, die wir gerade hatten, gehen wir nochmal

01:21:06.830 --> 01:21:13.490
zurück, da hatten wir nämlich gesagt, hier sind Tickets, die verweisen

01:21:13.490 --> 01:21:14.470
in Ticket rein.

01:21:14.990 --> 01:21:21.650
Und dann wollen wir also umgekehrt jetzt hier finden, die Buchungen,

01:21:22.170 --> 01:21:24.010
die in Ticket hineinverweisen.

01:21:24.130 --> 01:21:28.430
Das heißt, jetzt geben wir an, was ist in der Relation Buchung, wo

01:21:28.430 --> 01:21:31.990
steckt da der Verweis auf mich, nämlich unter Ticket.

01:21:31.990 --> 01:21:36.710
Und hier habe ich umgekehrt eben alle Buchungen aufgeführt, die unter

01:21:36.710 --> 01:21:37.550
dieses Ticket fallen.

01:21:38.210 --> 01:21:44.090
Und dann habe ich auch wieder hier einige Operationen angegeben, die

01:21:44.090 --> 01:21:45.430
jetzt auf das Ticket sich beziehen.

01:21:47.250 --> 01:21:50.970
Dann habe ich, Moment, jetzt war ich einen Schritt zu schnell, über

01:21:50.970 --> 01:21:53.570
Kunde hatte ich gesprochen, Buchung haben wir noch nicht gehabt, da

01:21:53.570 --> 01:21:54.930
war das, was ich vorhin gezeigt habe.

01:21:55.470 --> 01:21:58.110
Jetzt haben wir noch Buchung, da muss auch was existieren, richtig, da

01:21:58.110 --> 01:22:02.670
existiert auch, dass ich auf Ticket verweise und dass dort ja unter

01:22:02.670 --> 01:22:05.890
Buchung die Rückwärtsverweise zu finden sind.

01:22:06.370 --> 01:22:10.290
Also habe ich jetzt hier zwischen den drei Klassendefinitionen, habe

01:22:10.290 --> 01:22:13.730
ich jetzt jeweils referenzielle Konsistenzen aufgebaut, die ich dann

01:22:13.730 --> 01:22:17.870
in der konkreten Ausprägung eben sichern muss, indem mein

01:22:17.870 --> 01:22:21.010
Datenbanksystem sicherstellt, dass diese Relationship Inverse auch

01:22:21.010 --> 01:22:22.250
tatsächlich aufrechterhalten wird.

01:22:22.350 --> 01:22:24.790
Und sonst hat es Rückweis und sagt, das geht nicht, da ist keine

01:22:24.790 --> 01:22:26.170
referenzielle Konsistenz definiert.

01:22:27.790 --> 01:22:30.950
So, da haben wir auch ein paar Attribute und da haben wir noch eine

01:22:30.950 --> 01:22:33.690
Operation angegeben.

01:22:37.920 --> 01:22:43.980
Also eigentlich ist die ODL an der Stelle doch recht elegant, man kann

01:22:43.980 --> 01:22:47.520
alles ausdrücken, was sich hinter unseren Klassen verbirgt.

01:22:48.600 --> 01:22:54.920
Und die Tatsache, dass wir aber die ODL nicht verwenden, sondern dass

01:22:54.920 --> 01:23:00.200
wir eine interne Repräsentation des Schemas generieren, aus der

01:23:00.200 --> 01:23:06.400
Sprachenbindung, indem wir aus den Programmen selbst heraus die

01:23:06.400 --> 01:23:10.940
Typdefinition übernehmen, hat bei mir ein extrem ungutes Gefühl zur

01:23:10.940 --> 01:23:11.240
Folge.

01:23:12.740 --> 01:23:17.180
Denn ich habe mir die Definition beschafft aus Programmen, deren

01:23:17.180 --> 01:23:21.760
Lebensdauer mir überhaupt nicht klar ist und bisher war es ja so, dass

01:23:21.760 --> 01:23:24.720
das Schema, und zwar auch in einer Form, die verständlich ist, die man

01:23:24.720 --> 01:23:27.900
auch nacharbeiten kann, die man immer wieder einsehen kann, mit der

01:23:27.900 --> 01:23:29.000
Datenbasis geführt wird.

01:23:29.340 --> 01:23:32.900
Jetzt kriege ich nicht mehr eine ODL, also eine sprachneutrale

01:23:32.900 --> 01:23:35.560
Definition, irgendeine interne Darstellung, die zurück übersetzt

01:23:35.560 --> 01:23:36.080
werden muss.

01:23:37.960 --> 01:23:42.100
Da ist mir, wenn ich die lange Lebensdauer betrachte, reichlich

01:23:42.100 --> 01:23:42.620
unwohl.

01:23:43.600 --> 01:23:45.980
Und es ist interessant, dass auch Lebensdauerbetrachtungen für

01:23:45.980 --> 01:23:50.580
objektorientierte Datenbanken weitaus großzügiger und schludriger

01:23:50.580 --> 01:23:54.020
behandelt werden, als im relationalen Fall, wo wir sagen, die leben

01:23:54.020 --> 01:23:55.360
extrem lange.

01:23:57.120 --> 01:23:58.740
Das zweite ist die OQL.

01:23:59.840 --> 01:24:03.120
Bei der OQL müssen wir natürlich jetzt bedenken, dass wir, wenn wir

01:24:03.120 --> 01:24:10.140
sie schon verwenden, möglicherweise auch aus Anwendungsprogrammen

01:24:10.140 --> 01:24:11.240
heraus aufrufen.

01:24:11.640 --> 01:24:15.260
Und wenn wir das tun, dann wollen wir in jedem Fall erreichen, dass

01:24:15.260 --> 01:24:17.380
das Ergebnis wiederum typisiert ist.

01:24:17.620 --> 01:24:19.460
Im relationalen Fall kein Problem.

01:24:21.380 --> 01:24:23.360
Da bleiben wir immer generisch.

01:24:23.360 --> 01:24:27.820
Und da ist Sache, dass der Impedance mismatcht und irgendwie muss das

01:24:27.820 --> 01:24:31.260
Anwendungsprogramm sehen, wie es mit dem Ergebnis zurechtkommt.

01:24:31.460 --> 01:24:33.780
Aber hier sind wir typisiert, monomorph.

01:24:34.100 --> 01:24:37.260
Also bei der Objektorientierung erwarten wir, dass auch das Ergebnis

01:24:37.260 --> 01:24:38.340
typisiert ist.

01:24:38.740 --> 01:24:41.400
Ich führe Ihnen das jetzt so auf die Schnelle noch an ein paar

01:24:41.400 --> 01:24:44.780
Beispielen durch, nur damit Sie sehen, dass wir in der Tat auch Typen

01:24:44.780 --> 01:24:45.640
konstruieren können.

01:24:46.380 --> 01:24:49.400
Und zwar zunächst einmal, wenn wir literalen Objekte für sich

01:24:49.400 --> 01:24:53.720
betrachten, dann gibt es eben, so wie ja bei Programmiersprachen auch

01:24:53.720 --> 01:24:57.300
üblich, wird eben aus dem Wert zurückgeschlossen auf den Typ.

01:24:57.540 --> 01:25:00.800
Also wenn wir hier das hier schreiben, dann sagt uns das eben, aha,

01:25:01.060 --> 01:25:01.600
ein String.

01:25:02.800 --> 01:25:07.680
Und wenn hier steht Struct, dann ist auch nicht besonders viel

01:25:07.680 --> 01:25:10.960
aufwendiger zu sagen, aha, das ist in dem Nachhinein ein Struct.

01:25:11.040 --> 01:25:13.800
Und dann müssen wir jetzt noch hier das jeweils interpretieren.

01:25:14.000 --> 01:25:15.500
Und da sehen wir auch wieder, das sind Strings.

01:25:15.500 --> 01:25:20.340
Also wir generieren zunächst einmal aus den Werten selbst den

01:25:20.340 --> 01:25:21.240
entsprechenden Typ.

01:25:21.780 --> 01:25:27.520
Wenn da steht Kunde und dann gehen wir noch irgendwas zusätzlich an,

01:25:28.360 --> 01:25:31.280
dann entnehmen wir daraus, dass es sich um den Objekt Typ Kunde

01:25:31.280 --> 01:25:31.620
handelt.

01:25:31.740 --> 01:25:33.960
Brauchen wir auch nicht mehr zu sagen, denn wir haben ja die Typ

01:25:33.960 --> 01:25:37.120
-Definition, können danach sehen, von welchem Typ Kunde selbst ist,

01:25:37.220 --> 01:25:38.540
wie der intern aufgebaut ist.

01:25:38.980 --> 01:25:42.520
Und wenn wir hier Bergchen schreiben, dann müssen wir wieder sagen,

01:25:43.160 --> 01:25:45.000
wie sehen denn die Elemente aus.

01:25:45.000 --> 01:25:47.360
Und da schaut man sich das dann noch an und stellt fest, das ist ein

01:25:47.360 --> 01:25:48.180
Unsigned Short.

01:25:48.980 --> 01:25:51.660
Und das Ganze geht in einen Berg ein.

01:25:53.220 --> 01:25:58.640
Und wenn wir eine Extension definiert haben für eine Klasse, dann

01:25:58.640 --> 01:26:02.500
können wir auch sagen, dann ist das Ergebnis eine Menge.

01:26:03.440 --> 01:26:06.020
Jetzt sehen wir übrigens auch, dass wir Extensionen wirklich strikt

01:26:06.020 --> 01:26:08.780
als Menge interpretieren, und zwar die Menge von Kunden.

01:26:09.880 --> 01:26:11.940
Also aus primitiven Ausdrücken können wir zunächst einmal einen Typ

01:26:11.940 --> 01:26:14.920
generieren und das können wir dann anschließend weiterverwenden.

01:26:15.240 --> 01:26:18.270
Dann können wir hier auch wieder Funktionen betrachten.

01:26:18.780 --> 01:26:22.580
Da sehen Sie schon, in OQL werden auch, da sieht man natürlich genau,

01:26:22.720 --> 01:26:26.360
dass SQL Party gestanden hat und dass man sich nicht zu weit von SQL

01:26:26.360 --> 01:26:27.240
entfernen wollte.

01:26:28.060 --> 01:26:32.220
Es gibt also auch wieder neben den arithmetischen Operationen,

01:26:32.320 --> 01:26:35.560
insbesondere auch wieder die Aggregierungsfunktionen.

01:26:35.600 --> 01:26:38.020
Also Count, Min, Max, Sum, Average.

01:26:38.900 --> 01:26:41.980
Die sind jeweils auf Sets definiert.

01:26:45.140 --> 01:26:48.540
Und übrigens, glaube ich, sogar auf Kollektionen.

01:26:49.300 --> 01:26:51.100
Also sie sind auch anwettbar auf Bags.

01:26:51.980 --> 01:26:59.300
Und haben dann entweder einen numerischen Wert zum Ergebnis oder eben

01:26:59.300 --> 01:27:02.180
in dem anderen Fall ein Unsigned Long bei Zählungen.

01:27:04.780 --> 01:27:11.520
So, dann die Zugriffe auf einzelne Komponenten, die ja durch ihre

01:27:11.520 --> 01:27:13.140
Attribute gekennzeichnet sind.

01:27:13.260 --> 01:27:14.940
Sie erinnern sich, Objekte sind ja strukturiert.

01:27:15.560 --> 01:27:17.580
Das erfolgt einfach durch Punktnotationen auch.

01:27:17.660 --> 01:27:19.140
Nichts Neues, sind alles geläufig.

01:27:20.260 --> 01:27:26.080
Wenn ich also K-Name anschreibe, dann weiß ich, und K sein Kunde, dann

01:27:26.080 --> 01:27:30.140
weiß ich, wenn ich in das Schema reingehe, dann finde ich unter Kunde,

01:27:30.400 --> 01:27:35.800
dass unter Name die Domäne String ist.

01:27:35.940 --> 01:27:39.920
Also weiß ich, dass in Folge K Punktname von Typ String ist.

01:27:39.920 --> 01:27:41.700
Bei K Telefon Vorwahl.

01:27:42.180 --> 01:27:46.080
Da erinnern Sie sich noch, Telefon war ein strukturierter Typ.

01:27:46.220 --> 01:27:48.100
Also gehen wir noch einen Schritt weiter und gehen in den

01:27:48.100 --> 01:27:50.680
strukturierten Typ rein und holen uns da eine Komponente heraus.

01:27:51.120 --> 01:27:53.760
Das war Vorwahl und von Vorwahl wissen wir wieder, dass das String

01:27:53.760 --> 01:27:54.020
war.

01:27:55.260 --> 01:27:58.740
Und dann, wenn ich den Operator angebe, dann muss ich halt nachsehen

01:27:58.740 --> 01:28:01.880
in der Definition, in der Schnittstelle, was denn der Ergebnistyp

01:28:02.720 --> 01:28:03.840
dieses Operators ist.

01:28:04.020 --> 01:28:05.920
Und in dem Fall bei Storch hier ist der Void.

01:28:06.200 --> 01:28:07.360
Also ist das Ergebnis Void.

01:28:07.360 --> 01:28:10.160
Also das können wir alles sehr leicht feststellen.

01:28:10.500 --> 01:28:11.280
Ist auch nichts Neues.

01:28:12.120 --> 01:28:15.920
So und jetzt kommen wir so langsam in die Mengenorientierung rein und

01:28:15.920 --> 01:28:20.900
stellen also fest, da hätten wir auch wieder gerne so zunächst mal

01:28:20.900 --> 01:28:24.820
Quantifizierungen, zum Beispiel Alquantor und Existenzquantor.

01:28:25.440 --> 01:28:30.080
Beide hatten wir, wenn Sie sich erinnern, auch bei SQL und die beide

01:28:30.080 --> 01:28:34.060
konnten zurückgeführt werden auf Konstrukte in der Relationalen

01:28:34.060 --> 01:28:34.400
Algebra.

01:28:34.400 --> 01:28:39.700
Also entweder auf die Verbindungsoperation oder auch auf die Division.

01:28:42.020 --> 01:28:45.280
Und die werden jetzt sogar ein bisschen sauberer formuliert.

01:28:45.400 --> 01:28:51.500
Jetzt heißt es x in E, Doppelpunkt B und E ist ein Ausdruck und B ist

01:28:51.500 --> 01:28:52.500
eine Bedingung.

01:28:53.620 --> 01:28:57.300
Das heißt, wir sagen einfach, wir prüfen nach, in der E im ersten Fall

01:28:57.300 --> 01:29:02.940
existiert ein Element in E, das heißt im Ergebnis der Ausführung des

01:29:02.940 --> 01:29:06.440
Ausdrucks E, der die Bedingung erfüllt und bei All heißt es halt,

01:29:06.560 --> 01:29:13.860
erfüllen alle Elemente in der Ergebnismenge, die aus E gewonnen wird,

01:29:14.120 --> 01:29:14.700
die Bedingung B.

01:29:15.600 --> 01:29:19.520
Zum Beispiel können wir an dieser Stelle dann sagen, wir können mal

01:29:19.520 --> 01:29:25.240
nachprüfen, ob es in der Menge der Tickets eines Kunden klein k, also

01:29:25.240 --> 01:29:31.920
klein k als Variable, ob dort ein Ticket mit der Nummer existiert 4711

01:29:31.920 --> 01:29:35.060
oder dass vielmehr die Zeichenkette 4711 erhält.

01:29:35.780 --> 01:29:38.300
Und dann werden noch Kurzformen genommen, damit man auch noch

01:29:38.300 --> 01:29:40.320
möglichst nahe an SQL liegt.

01:29:40.860 --> 01:29:41.920
Daraus sehen Sie folgendes.

01:29:42.080 --> 01:29:46.500
SQL ist sozusagen heute der Gradmesser aller deskriptiven Sprachen.

01:29:46.980 --> 01:29:50.340
Deshalb finden Sie heute SQL-ähnliche Sprachen in allen möglichen

01:29:50.340 --> 01:29:52.960
Anwendungsgebieten, auch außerhalb des Datenbankbereichs.

01:29:53.400 --> 01:29:56.600
Also man klammert sich so richtig an SQL an, weil SQL versteht jeder,

01:29:56.880 --> 01:30:01.960
glaubt man wenigstens, und versucht also alle Konstrukte irgendwie in

01:30:01.960 --> 01:30:03.920
diese SQL-Welt zu packen.

01:30:04.220 --> 01:30:05.460
Und das sehen wir auch an dieser Stelle.

01:30:06.920 --> 01:30:10.720
Da wird nämlich jetzt einfach gesagt SELECT DISTINCT und dann kommt

01:30:10.720 --> 01:30:14.280
ein Ausdruck E, der kann beliebig sein, kann also selbst ein SELECT

01:30:14.280 --> 01:30:14.920
-Ausdruck sein.

01:30:15.800 --> 01:30:19.120
Dann kommt das FROM, das kennen wir auch, das ist so ähnlich wie das,

01:30:19.160 --> 01:30:21.540
was wir am Ende bei SQL schon kennengelernt haben.

01:30:21.620 --> 01:30:25.660
Ich gebe Ausdrücke an und dann prüfe ich nach, dann definiere ich

01:30:25.660 --> 01:30:28.060
Variablen von x1, x2 und so weiter bis xn.

01:30:28.600 --> 01:30:31.520
Dann kommt eine Bedingung, die das Ganze überprüft und schließlich

01:30:31.520 --> 01:30:33.780
kommt ein ORDER BY, ich kann also auch noch ordnen.

01:30:33.920 --> 01:30:36.040
Und dann sieht man auch, ich kann über den Ergebnismatzyklus etwas

01:30:36.040 --> 01:30:39.660
aussagen, wenn ich ORDER BY hinschreibe, ist das Ergebnis LISTE.

01:30:40.220 --> 01:30:45.000
Wenn ich DISTINCT schreibe, aber nicht ORDER BY, ist es ein SET.

01:30:45.280 --> 01:30:47.860
Und wenn weder das eine noch das andere da ist, dann ist es ein BACK.

01:30:49.860 --> 01:30:50.000
So.

01:30:50.860 --> 01:30:53.640
Und dann gibt es noch eine Semantik zu dem Ausdruck, die ist auch ganz

01:30:53.640 --> 01:30:59.220
ähnlich wie die, die wir in SQL vorgefunden haben.

01:30:59.360 --> 01:31:03.720
Ich nehme wieder die FORM-Klausel, werte alle Ausdrücke aus und

01:31:03.720 --> 01:31:08.340
konvertiere jetzt die Ergebnisse, in dem Fall BACKS.

01:31:08.900 --> 01:31:14.360
Dann bilde ich alle Tuple aus den Kombinationen dieser x1 bis xn.

01:31:15.160 --> 01:31:17.200
Das heißt, ich mache eigentlich sowas wie ein kathesisches Produkt.

01:31:18.220 --> 01:31:20.980
Dann eliminiere ich die Tuple, die die Bedingungen aus der WEHR

01:31:20.980 --> 01:31:22.520
-Klausel nicht erfüllen.

01:31:23.640 --> 01:31:26.100
Dann werde ich auf den verbleibenden Tuple

01:31:29.920 --> 01:31:32.960
wende ich den Ausdruck E an, der also irgendwie jetzt auch auf diese

01:31:32.960 --> 01:31:38.640
Variablen Bezug nimmt, x1 bis xn, und füge dann das Resultat, das

01:31:38.640 --> 01:31:41.640
irgendein Objekt ist, in eine Ergebnismenge ein und am Schluss kann

01:31:41.640 --> 01:31:42.940
ich das Ganze noch sortieren.

01:31:44.580 --> 01:31:44.580
So.

01:31:44.920 --> 01:31:46.820
Und da kann man sich auch vorstellen, so wird man es natürlich in

01:31:46.820 --> 01:31:47.960
Praxis dann noch nicht machen.

01:31:48.080 --> 01:31:50.740
Dahinter ist also gefälligst, hat wie ein Optimierer zu stehen, der

01:31:50.740 --> 01:31:54.040
den Ausdruck nimmt und einfach davon etwas Effizienteres macht.

01:31:55.340 --> 01:31:58.340
Ansonsten lade ich Sie hier ein, sich da noch so ein paar Beispiele

01:31:58.340 --> 01:31:59.080
anzusehen.

01:32:00.280 --> 01:32:02.720
Das ist eine Fingerübung, sich die anzusehen.

01:32:02.780 --> 01:32:07.000
Hier sehen Sie zum Beispiel, dass ich einfach Namen und Telefonnummern

01:32:07.000 --> 01:32:08.300
aller Kunden aus Berlin nehme.

01:32:08.380 --> 01:32:09.160
Das ist noch ganz einfach.

01:32:09.320 --> 01:32:10.740
Das Ergebnis wird ein Struct.

01:32:10.960 --> 01:32:12.580
Daraus mache ich jetzt einen Bag.

01:32:13.780 --> 01:32:17.840
Ich habe noch eine einzige Extension, nämlich die Kunde.

01:32:18.240 --> 01:32:19.640
Das ist die Variable K.

01:32:20.020 --> 01:32:21.880
Hier wird sie verwendet, für den Wehrausdruck.

01:32:22.240 --> 01:32:25.860
Hier wird sie konstruieren.

01:32:34.890 --> 01:32:38.770
Ich hier zunächst einmal einen Bag konstruieren und mit diesem Bag

01:32:38.770 --> 01:32:40.390
dann die Zählung laufen lasse.

01:32:40.810 --> 01:32:43.150
Hier sehen Sie übrigens noch mal die Variable vor.

01:32:43.550 --> 01:32:45.990
Und da sehen Sie auch, dass ich darunter automatisch die Variable

01:32:45.990 --> 01:32:46.530
erzeugen kann.

01:32:46.810 --> 01:32:49.390
Ich zeige nur hier, dass wir noch mehrere Beispiele haben.

01:32:49.710 --> 01:32:51.950
Hier sehen Sie zum Beispiel einen, wo uns der Ergebnis bereits in den

01:32:51.950 --> 01:32:53.210
Select -Ausdruck reinkommt.

01:32:53.730 --> 01:32:57.030
Das heißt und zwar, ich baue eine Untermenge in das Ergebnis ein.

01:32:57.170 --> 01:33:00.450
Das ist nicht mehr flach, sondern jetzt strukturiert, indem ich eine

01:33:00.450 --> 01:33:01.910
Menge unter Tickets unterbringe.

01:33:03.110 --> 01:33:07.250
Dann kann ich hier jetzt auch Count Bedingungen angeben.

01:33:07.510 --> 01:33:10.050
Zum Beispiel kann ich zählen über einer Menge.

01:33:10.570 --> 01:33:13.730
Und weil das aber nicht so formuliert werden könnte in SQL, darum gibt

01:33:13.730 --> 01:33:16.970
es auch noch eine äquivalente Formulierung, die der SQL-Welt ähnlich

01:33:16.970 --> 01:33:17.610
aussieht.

01:33:18.490 --> 01:33:20.910
Dann habe ich hier noch einen, wo Sie sehen, dass ich auch wieder

01:33:21.390 --> 01:33:22.930
verschachtelte Ausdrücke konstruieren kann.

01:33:23.050 --> 01:33:24.890
Alles aber komplizierter als im SQL-Fall.

01:33:26.170 --> 01:33:27.410
Und das waren so ein paar Beispiele.

01:33:27.710 --> 01:33:29.030
Die schauen Sie sich mal an in Ruhe.

01:33:29.350 --> 01:33:31.690
Dass ich hier schnell durchgegangen bin, wie gesagt, hängt damit

01:33:31.690 --> 01:33:36.890
zusammen, dass wir eigentlich OQL kaum in Praxis finden, dass viele

01:33:36.890 --> 01:33:38.290
Anbieter sie gar nicht anbieten.

01:33:38.790 --> 01:33:43.650
Aber was daran interessant ist, diese Konstruktionen haben eine

01:33:43.650 --> 01:33:46.810
gewisse Rückwirkung auf die neueren Standards von SQL gehabt.

01:33:46.810 --> 01:33:50.490
Jetzt kann man nämlich in der neuesten Fassung von SQL auch in die

01:33:50.490 --> 01:33:53.590
Ergebnis -Klausel, die Select-Klausel, auch solche Schachteln

01:33:53.590 --> 01:33:54.090
einbauen.

01:33:54.450 --> 01:33:55.910
Da werden Sie also gelegentlich draufstoßen.

01:33:56.530 --> 01:34:00.590
So, damit haben wir zunächst einmal sozusagen die Schnittstelle, die

01:34:00.590 --> 01:34:04.190
Welt, die funktionale Schnittstelle der Datenbanksysteme

01:34:04.190 --> 01:34:04.750
kennengelernt.

01:34:05.350 --> 01:34:08.330
Erinnern Sie sich noch, dass ich gesagt hatte, wir müssen ein Spagat

01:34:08.330 --> 01:34:11.610
machen von der Mini-Welt, die wir in unseren eigenen

01:34:13.390 --> 01:34:16.330
Anwendungsbegriffen erfassen, in die Welt der Datenbanken, wo wir das

01:34:16.330 --> 01:34:17.450
Datenmodell verwenden.

01:34:17.890 --> 01:34:19.770
Und diesen Spagat, den betrachten wir nächste Woche.

01:34:24.690 --> 01:34:26.090
Langsam da, Frau Millip.

01:34:26.930 --> 01:34:27.910
Ja, heute sind Übungen.

01:34:28.390 --> 01:34:29.090
Da hat sie noch zu sagen.

01:34:40.520 --> 01:34:41.640
Ja, das macht nichts.

01:34:53.000 --> 01:34:54.100
Aber immerhin.

