Objektorientierte Datenbanken -- Entstehung, Konzepte, Systeme

Jutta Göers, Fachbereich Mathematik-Informatik, Universität Osnabrück

Mit objektorientierten Datenbanksystemen (OODBS) versucht man heute, die Komplexität vieler Anwendungen in den Griff zu bekommen. Doch gibt es im Gegensatz zu relationalen Datenbanksystemen kein einheitliches Datenmodell, das allen (kommerziellen) OODBS zugrundeliegt. Im Folgenden werden die Entstehungsgeschichte, einige Systeme und diejenigen Konzepte, die von verschiedenen Seiten für objektorientierte Datenmodelle gefordert werden, beschrieben.

Entstehungsgeschichte

Mit zunehmender Komplexität vieler Anwendungen, z.B. in den Bereichen CAD/CAM , CASE , Bürokommunikation oder Expertensysteme, merkt man, daß die Fähigkeiten der klassischen Datenbankmodelle nicht ausreichen.

In der Praxis stellt sich die Situation so dar, daß inzwischen das relationale Datenbankmodell von Codd aufgrund seiner leichten Verständlichkeit und einfachen Abfragesprache das hierarchische und das Netzwerk-Modell abgelöst hat. Doch auch bezüglich des relationalen Modells kommt viel Kritik von den Anwendern. So seien z.B. relationale Datenbanksysteme langsamer als hierarchische oder auf dem Netzwerk-Modell beruhende, und die Verteilung (und bei Anfragen notwendige Verknüpfung) von Daten auf mehrere Tabellen sei umständlich. Neben solcher gibt es aber auch Kritik am Modell an sich, weil sich die Daten komplexer Anwendungen nicht realitätsnah modellieren lassen.

Ein Beispiel: Sind zu einem Buch neben ISBN und Titel noch mehrere Autoren zu speichern, so ist dieses im relationalen Modell nur mit viel Datenredundanz oder über zwei Relationen zu machen. Mit Redundanz ergibt sich beispielsweise

                   ISBN   TITEL      AUTOR
                   __________________________
                   1111   aaa     Müller
                   1111   aaa     Schulz
                   2222   kkk     Meier
                   3333   bbb     Werner
                   3333   bbb     Lang
                   3333   bbb     Bauer

Bei Aufteilen in zwei Relationen entfällt die Datenredundanz:

              ISBN   TITEL      ISBN      AUTOR
              _____________    ___________________
              1111   aaa        1111   Müller
              2222   kkk        1111   Schulz
              3333   bbb        2222   Meier
                                3333   Werner
                                3333   Lang
                                3333   Bauer

Um solche Nachteile zu beheben, entwickelte man die sogenannten semantischen Datenbankmodelle. Ziel dieser Modelle war es, eine adäquate Modellierung der Anwendungsdaten zu ermöglichen. So bieten die semantischen Modelle unter anderem spezielle Beziehungen (Is-a-Beziehungen) und Typkonstruktoren, mit denen man Mengen oder Tupel von Daten bilden kann.

Gleichzeitig gab es ähnliche Entwicklungen in einem anderen Gebiet der Informatik: den Programmiersprachen. So wurden objektorientierte Programmiersprachen entwickelt, die im Vergleich zu herkömmlichen Sprachen ein verallgemeinertes Typkonzept besitzen. Dieses erlaubt, daß neben Werten (Attributen) auch Methoden Bestandteile von Record-Strukturen sein können und daß diese Methoden und Attribute zusammen die Definition einer Klasse bilden. Beispiele hierfür sind die Sprachen Turbo-Pascal oder C++.

Doch schon lange vor diesen Entwicklungen existierte die Sprache SMALLTALK , die auf einem reinen Klassenkonzept beruht. So ist in SMALLTALK jeder Standardtyp (z.B. Integer) durch eine Klasse repräsentiert. Die Integerzahlen sind die Objekte (Instanzen) dieser Klasse. Sollen zwei Integerzahlen addiert werden, so ``schickt'' die eine Zahl eine Botschaft ``addiere'' mit ihrem eigenen Wert als Parameter an die andere Zahl. Diese führt dann eine entsprechende Methode (hier: Addition) aus und schickt das Ergebnis zurück.

Zu den Klassen bieten alle objektorientierten Sprachen Vererbungsstrukturen, teilweise mit Mehrfachvererbung, Overriding und weitere Konzepte.

Die Entwicklung von objektorientierten Datenbanksystemen begann nun in beiden Gebieten, dem der (semantischen) Datenbanksysteme und dem der objektorientierten Programmiersprachen, siehe Abbildung 1.

Abbildung 1: Entwicklung von objektorientierten Datenbanksystemen (nach [Heu92])

Objektorientierte Programmiersprachen erweiterte man um Datenbankkomponenten wie persistente Speicherung von Objekten, Speicherstrukturen für Mengen von Objekten und um für Datenbankanwendungen wichtige Operatoren. So entstandene Datenbanksysteme zählen zu den operational oder verhaltensmäßig objektorientierten Datenbanksystemen [Dit86, Dit88, DK89], da die Fähigkeiten der Programmiersprachen zwar zur Beschreibung des Verhaltens von Objekten genutzt werden, die komplexe Struktur der Objekte jedoch mit herkömmlichen Mitteln beschrieben wird.

Bei der Erweiterung der herkömmlichen (semantischen) Datenbanksysteme fügte man schrittweise objektorientierte Konzepte wie Typkonstruktoren, Objektidentität, Klassen usw. hinzu. Diese Entwicklung berücksichtigte speziell die komplexe Struktur von Anwendungsobjekten, die Beschreibung des Verhaltens wurde oft vernachlässigt. Aus diesem Grund bezeichnet man so entstandene Datenbanksysteme als strukturell objektorientiert.

In den letzten Jahren begannen Bestrebungen, einen allgemein akzeptierten ``Standard'' für objektorientierte Datenbankmodelle und -systeme (OODBS) zu setzen. So enthält das MANIFESTO [ABD+89] eine Liste unbedingt notwendiger, optionaler und offener Bestandteile eines OODBS , und Beeri versucht in [Bee89, Bee90], Anforderungen an objektorientierte Datenbankmodelle zu formalisieren. Neben diesen Standardisierungsbestrebungen von wissenschaftlicher Seite gibt es auch Ansätze von kommerziellen Vertretern. So haben sich in der Object Database Management Group (ODMG) Anbieter von objektorientierten Datenbanksystemen zusammengetan, um einen Standard für ihre Produkte zu entwickeln. Dabei werden die Architektur, das Objektmodell, eine Objektdefinitionssprache, eine Anfragesprache und Schnittstellen zu Programmiersprachen in die Standardisierung einbezogen.

Konzepte

Im Folgenden werden die Konzepte voll objektorientierter Datenbanksysteme, also sowohl strukturelle als auch operationale, näher erläutert.

Strukturelle Konzepte

Typkonstruktoren: Jedes Datenbankmodell basiert auf einer Reihe von Standarddatentypen, wie INTEGER , REAL oder CHARACTER . Ihnen zugeordnet sind sogenannte Domänen, die die Menge der erlaubten Werte dieses Typs beschreiben. Neben diesen Standardtypen bieten manche Datenmodelle anwendungsbezogene Typen wie DATE oder TIME . Da diese nicht ausreichen, um die komplexe Struktur mancher Anwendungsobjekte zu modellieren, gibt es Typkonstruktoren, die, rekursiv angewendet, die kompliziertesten Typen aufbauen können:

Der Tupelkonstruktor faßt mehrere Komponenten unterschiedlichen Typs zu einem neuen Typ zusammen. Der Mengenkonstruktor erzeugt aus mehreren Elementen des gleichen Typs einen neuen Typ. Der Listenkonstruktor faßt ebenfalls Elemente eines Typs zusammen, allerdings zu einem ``geordneten'' Typ.

Ein Beispiel: Modelliert werden soll eine Klasse von Personen, zu denen jeweils der Name, bestehend aus Vor- und Nachnamen, das Geburtsdatum, die Kinder und die Hobbies angegeben sind. Den Typ dieser Klasse zeigt Abbildung 2.

SET OF ( TUPLE OF ( Name : TUPLE OF ( Vorname: STRING[30],
                                      Nachname: STRING[30] ),
                    Geburtsdatum: DATE,
                    Kinder: LIST OF (Kind: STRING[30]),
                    Hobbies: SET OF (Hobby: STRING[20])
                   ))

Abbildung 2: Typkonstruktoren

Objekte der Klasse (Instanzen) wären zum Beispiel

{ ((Adam, Zeisig), 1.12.1950,
   [Kain, Abel, Maria],
   {Segeln, Skat}),
  ((Eva, Zeisig), 30.6.1955,
   [Kain, Abel, Maria],
   {Segeln, Lesen, Golf})
}

Komplexe Objekte: Mittels derartiger Typkonstruktoren lassen sich nun beliebig komplexe Typen definieren. Objekte, deren Struktur ein solcher komplexer Typ ist, werden häufig als komplexe Objekte bezeichnet.

Komplexe Strukturen nützen natürlich nichts, wenn man nicht mit ihnen arbeiten kann. Deshalb gehören zu den Typkonstruktoren Standardoperationen, mit denen man

Objektidentität: Im relationalen Datenmodell benutzt man Schlüssel(attribute) zum Identifizieren von Datentupeln, d.h., der Wert des Schlüssels identifiziert eindeutig ein Tupel. Ändert sich jedoch einmal der Wert des Schlüsselattributs, so ist nicht mehr nachvollziehbar, um welches Tupel es sich vorher handelte. Darüber hinaus muß diese Wertänderung in allen anderen Relationen, die das Schlüsselattribut enthalten, nachgezogen werden.

Beispiel: Bei der Modellierung von Personen (siehe obiges Beispiel) im relationalen Modell würde man wohl den Vornamen, den Nachnamen und das Geburtsdatum als Schlüssel wählen. Heiratet nun eine Person, wird also z.B. aus (Eva Specht, 30.6.1955, ...) (Eva Zeisig, 30.6.1955, ...), so ist nach der Änderung nicht mehr nachvollziehbar, daß die ``neue'' Eva Zeisig mit der ``alten'' Eva Specht übereinstimmt.

Objektorientierte Datenbanksysteme sollten daher die Objektidentität unterstützen, bei der jedes Objekt seine unveränderbare Identität hat, die unabhängig von den Attributwerten ist und vom System vergeben und verwaltet wird. Zur Realisierung der Objektidentität kann zum Beispiel die physikalische Adresse des Objekts genommen werden, ein zusätzlicher Name oder auch ein zusätzliches Identifier-Attribut (Surrogat).

Klassen und Typen: So wie im relationalen Modell Tupel gleicher Struktur zu einer Relation gehören, faßt man Objekte mit gleichen Eigenschaften (Struktur und Verhalten) zu einer Menge zusammen. Man unterscheidet drei Arten von Schemata:

Das MANIFESTO fordert alle drei Arten zur Schemadefinition, Beeri nur das Klassen-Typ-basierte Schema. Wir wollen im Folgenden von einem rein Klassen-Typ-basierten Schema ausgehen, bei dem Typen und Klassen nebeneinander existieren. In einem solchen Schema wird eine Klasse beschrieben durch

Abbildung 4 zeigt diese Funktion, die auf der Ebene der Instanzen definiert ist.

Abbildung 4: Klassen-Typ-basiertes Schema mit Instanzen

Alle Operationen, die auf Objekte und Werte angewendet werden können, lassen sich auch auf Klassen und Typen anwenden. Dabei wird die Operation auf alle Objekte einer Klasse angewendet. Zusätzlich gibt es auf Klassen noch Operationen zum Erzeugen und Löschen von Objekten ( NEW bzw. CREATE , DELETE bzw. FORGET ).

Beziehungen zwischen Klassen: Man unterscheidet zwei grundlegende Arten von Beziehungen zwischen Klassen. Zum einen gibt es die Beziehung zwischen einer Klasse und ihrer Komponentenklasse (Klasse-Komponentenklasse-Beziehung), zum anderen die Beziehung zwischen einer Klasse und ihrer Unterklasse (Klasse-Unterklasse-Beziehung).

Bei einer Klasse-Komponentenklasse-Beziehung hat ein Objekt ein anderes oder mehrere andere Objekte als Komponente(n). Kann ein Komponentenobjekt dabei Komponente mehrerer Objekte sein, so spricht man von einem gemeinsamen Komponentenobjekt, ansonsten ist es ein privates Komponentenobjekt. Hängt das Komponentenobjekt in seiner Existenz von dem übergeordneten Objekt ab (wird mit ihm zusammen erzeugt und wieder gelöscht), so nennt man es abhängig -- andernfalls unabhängig. Läßt sich nur von dem zusammengesetzten Objekt aus auf sein Komponentenobjekt zugreifen, so ist das Komponentenobjekt eingekapselt. Unabhängige Komponentenobjekte sind somit normalerweise nicht eingekapselt.

Beispiel: Soll zu einer Person noch der PKW angegeben werden, den diese Person zur Zeit besitzt, so läßt sich der PKW als ein Komponentenobjekt modellieren, siehe Abbildung 3.

CLASS Person
ATTRIBUTES Name: TUPLE OF ( Vorname: STRING[30],
                            Nachname: STRING[30] ),
           Geburtsdatum: DATE,
           Kinder: LIST OF (Kind: STRING[30]),
           Hobbies: SET OF (Hobby: STRING[20]),
           Auto: PKW
                          ...
CLASS PKW
ATTRIBUTES Kennzeichen: STRING[8],
           Kfz-Nummer: ...

Abbildung 3: Modellierung von PKW als Komponentenobjekt

Da ein Auto in seiner Existenz nicht von der Existenz des (derzeitigen) Besitzers abhängt, ist es unabhängig. Des weiteren soll es nicht eingekapselt sein, damit man nicht nur über seinen Besitzer auf das Auto zugreifen kann. Nehmen wir an, daß das Auto in einen Unfall verwickelt sein kann und damit gleichzeitig als Komponente eines Unfallobjekts auftritt, so ist es ein gemeinsames Komponentenobjekt.

Die meisten objektorientierten Datenmodelle unterstützen nur wenige Ausprägungen von Klasse-Komponentenklasse-Beziehungen. Die meistunterstützte ist ein gemeinsames, unabhängiges und nicht eingekapseltes Komponentenobjekt (wie im obigen Beispiel). Die wichtigste zusätzliche Operation auf dieser Art von Beziehung ist das ``Verfolgen'' der Beziehung. Dies geschieht mit der bekannten ``dot-Notation''. So kann man mit Person.Auto.Kfz-Nummer die Beziehung verfolgen und auf die gewünschte Information zugreifen.

Strukturvererbung: Neben der Beziehung zwischen einer Klasse und ihrer Komponentenklasse gibt es die Klasse-Unterklasse-Beziehung. Diese Beziehung wird durch die sogenannte Strukturhierarchie dargestellt. Dabei kann mit Strukturhierarchie eine Is-a-Hierarchie, eine Typ- oder eine Klassenhierarchie gemeint sein.

Bei einer Typhierarchie ist ein Typ T spezieller als ein Typ T', wenn der Wertebereich von T' den von T umfaßt und bei Tupeltypen T dieselben oder mehr Komponenten als T' besitzt bzw. bei Mengen- oder Listentypen der Typ der Elemente von T spezieller ist als der von den Elementen von T'. T heißt dann Untertyp von T', T' Obertyp von T.

Bei einer Klassenhierarchie ist eine Klasse K spezieller als eine Klasse K', wenn die Objektmenge von K Teilmenge der Objektmenge von K' ist. K heißt dann Unterklasse von K', K' Oberklasse von K. Die Unterklasse hat damit weniger Objekte als ihre Oberklasse.

Von einer Is-a-Hierarchie spricht man, wenn eine Klasse K bezüglich der Klassenhierarchie spezieller ist als eine Klasse K' und der zu K gehörende Zustandstyp T bezüglich der Typhierarchie spezieller als der Zustandstyp von K'. Bei einer Is-a-Hierarchie stimmen damit Klassen- und Typhierarchie überein.

Über die Strukturhierarchie wird nun die Vererbung von Attributen und Methoden mit den zugehörigen Implementierungs- und Instanzinformationen gesteuert.

Beispiel: Neben Personen sollen Angestellte und Studenten als Klassen modelliert werden. Da sowohl Angestellte als auch Studenten spezielle Personen sind, die neben den Attributen zu Personen weitere Eigenschaften aufweisen, bilden wir zwei Unterklassen zur Klasse Person:

CLASS Angestellter : Person
ATTRIBUTES Gehalt: REAL
           ...

CLASS Student : Person
ATTRIBUTES Matrikelnr.: INTEGER
          ...

Nun gibt es spezielle Studenten, die als Hilfskräfte an der Universität beschäftigt sind. Diese ``HiWis'' sind sowohl Studenten als auch Angestellte. Damit modellieren wir sie als Unterklasse der Klassen Student und Angestellter:

CLASS HiWi : Student, Angestellter
ATTRIBUTES Projekt: STRING[30]
           ...

Dieses Beispiel zeigt, daß eine Hierarchie ein beliebiger gerichteter azyklischer Graph sein kann. Des weiteren liegt eine Is-a-Hierarchie vor, da Typ- und Klassenhierarchie einander entsprechen, siehe Abbildung 4.

Es gibt objektorientierte Datenbankmodelle, die bezüglich der Art der Hierarchie noch eine weitere Unterscheidung machen. Sie trennen zwischen Spezialisierungen und Generalisierungen. Bei einer Spezialisierung werden die Objekte der Unterklasse aus den Objekten der Oberklasse ermittelt (``Welche Personen sind an einer Uni immatrikuliert und daher Studenten?''). Bei einer Generalisierung werden die Objekte der Oberklasse aus denen der Unterklasse ermittelt (Alle Angestellte und alle Geräte [aus einer Klasse ``Geräte''] bilden zusammen die Objekte einer Klasse ``Haushaltspositionen''.). Die Vererbung geschieht aber immer in der Hierarchie ``von oben nach unten'', das heißt von der allgemeineren Klasse an die speziellere.

Integritätsbedingungen: Integritätsbedingungen zählen zu den optionalen Konzepten objektorientierter Datenmodelle und sind deshalb selten zu finden. Zwei wollen wir hier dennoch kurz betrachten: Schlüssel und Kardinalitäten.

Schlüssel sind trotz systeminterner Objektidentifikatoren sinnvoll. Durch Angabe eines Schlüssels, d.h. einer Kombination von Attributen, deren Werte ein Objekt eindeutig identifizieren, kann der Benutzer leichter auf Objekte zugreifen. Der Objektidentifikator kann dafür nicht verwendet werden, denn er ist ja für den Benutzer unsichtbar. Schlüssel werden vererbt, sie können sich aus komplexen Attributen zusammensetzen, und auch Komponentenobjekte können zum Schlüssel gehören.

Kardinalitäten von Beziehungen (n:m, 1:n, 1:1), so wie man sie vom relationalen Modell her kennt, sind zumeist implizit in den Konzepten objektorientierter Datenmodelle enthalten. So sind n:m-Beziehungen der Normalfall, 1:n-Beziehungen können mittels Komponentenklassen modelliert werden und 1:1-Beziehungen über Schlüssel. Zusätzlich können Kardinalitäten von Mengen (Mindest- und Maximalanzahl) festgelegt werden.

Operationale Konzepte

Viele objektorientierte Datenbanksysteme enthalten gar keinen operationalen Teil, da dieser scheinbar durch das Konzept der Methode abgedeckt wird. Durch eine Implementierung mittels einer (objektorientierten) Programmiersprache stellen Methoden die volle Mächtigkeit solcher Sprachen zur Verfügung. Anfrageoperationen werden dann durch Standard-Methoden auf Klassen modelliert. Bei dieser Modellierung verliert man aber eine gute Optimierbarkeit, so wie sie z.B. bei der Relationenalgebra gegeben ist, und kann nicht alle Anfragen darstellen. Außerdem kann eine Methodenimplementierung vom Programmierer durch eine andere Implementierung überschrieben werden.

Generische Operationen: Aus diesen Gründen sind vordefinierte Operationen sinnvoll, die nicht einer einzelnen Klasse oder einem Objekt zugeordnet sind -- die sogenannten generische Operationen. Diese Operationen können somit auf alle Arten von Objektmengen angewandt werden und müssen nicht explizit erzeugt oder definiert werden. Man unterscheidet zwischen generischen Operationen, die auf Typen arbeiten und die Typhierarchie verändern können, und solchen, die auf Klassen arbeiten und die Klassenhierarchie verändern können. Beispiele von Operationen auf Typen sind Projektion, Umstrukturierung, Erweiterung und Verbund, Beispiele von Operationen auf Klassen sind Objekterzeugung, Selektion, Durchschnitt, Differenz und Vereinigung.

Allgemein fordert man von den generischen Operationen, daß sie abgeschlossen, adäquat, effizient, optimierbar und mächtig (``mindestens so mächtig wie relationale Sprachen'') sein sollen. Unter Abgeschlossenheit versteht man, daß das Anfrageergebnis wieder konsistent im Datenbankmodell darstellbar ist. Adäquat sind die Operationen dann, wenn alle Datenmodellkonstrukte in Anfragen und zur Darstellung von Anfrageergebnissen ausgenutzt werden können.

Aber generische Operationen haben den Nachteil, daß sie der Forderung nach Einkapselung widersprechen: Für generische Operationen ist der Zustandstyp einer Klasse sichtbar, welcher bei Einkapselung jedoch verborgen sein sollte.

Bei generischen Operationen kann man zwischen relationalen, objekterhaltenden und objektgenerierenden unterscheiden.

Relationale Operationen ``betrachten'' die Objekte bzw. deren Zustände einfach als geschachtelte Relationen oder Menge komplexer Werte. Auch die Objektidentität wird wie ein normaler Wert behandelt. Zu den relationalen Operationen zählen z.B. die Projektion, die Selektion, die Umbenennung, der Verbund, das Nesten und Entnesten.

Durch objekterzeugende Operationen werden neue (Ergebnis-) Klassen und neue Objekte in diesen Klassen erzeugt. Zu diesen Operationen zählen z.B. die objekterzeugende Umbenennung und Projektion und das Kreuzprodukt.

Objekterhaltende Operationen wahren die Objektidentität der an der Abfrage beteiligten Objekte. Da aber das Anfrageergebnis in die existierende Klassen- und Typhierarchie eingeordnet werden muß, können solche Operationen nicht immer angewendet werden und Inkonsistenzen erzeugen. Beispiele solcher Operationen sind die objekterhaltende Projektion, Selektion, Umbenennung und Restrukturierungen.

Weitere höhere Konzepte

Neben den operationalen Konzepten gehören noch weitere Konzepte zum dynamischen Teil von objektorientierten Datenbanksystemen. Diese sind die Metaklassen, die Definition und Vererbung von Methoden, Overriding und Mehrfachvererbung und die abstrakten Datentypen.

Metaklassen: Schon in relationalen Datenbanksystemen gab es eine Stelle, an der alle Informationen über die Relationen gespeichert wurden: das Data Dictionary/Directory. In objektorientierten Datenbanksystemen kann diese Metainformation in den sogenannten Metaklassen abgelegt werden. Neben der Information, welche Klassen vorhanden sind, welche Attribute die Klassen haben und von welchem Typ diese Attribute sind, können mittels Metaklassen auch die Methodenimplementierungen und das Overriding (s.u.) modelliert werden. Für diese Modellierung auf der Metaebene stehen alle Konzepte des zugrundeliegenden Datenmodells zur Verfügung.

Methoden: Wie oben bereits erwähnt, stellen Methoden die objektspezifischen Operationen auf Klassen bzw. Objekten dar. Man kann zwischen Anfrage- und Updatemethoden unterscheiden. Anfragemethoden sind Funktionen, die auf Objekte bzw. ihren Typ angewendet werden, einen beliebigen Typ als Ergebnis liefern und dabei den Zustand des betroffenen Objekts nicht ändern. Updatemethoden dagegen ändern gerade den Zustand des aufrufenden Objekts.

Methoden werden (wie Attribute) entlang der Klassenhierarchie vererbt.

Abstrakte Datentypen (ADT): Dieses sind Typen, deren Struktur ``nach außen'' nicht sichtbar und damit nicht bekannt ist. Man kennt nur die Methoden(köpfe), die zu diesem Typ definiert sind. Auch den generischen Operationen ist die Struktur verborgen, wodurch nur mit speziellen Anfrage- und Updateoperationen auf den ADT s gearbeitet werden kann. Dieses Verstecken der Struktur nennt man Einkapselung.

Overriding und Mehrfachvererbung: Unter Overriding versteht man das Redefinieren und damit Überschreiben von geerbten Attributwerten oder Methoden. Erbt eine Klasse K eine Methode M von einer Oberklasse, so kann die Implementierung von M für K überschrieben werden. Wird nun für ein Objekt der Klasse K die Methode M aufgerufen, so wird die zur Klasse K gehörende Implementierung ausgeführt.

Was passiert nun, wenn eine Klasse zwei Oberklassen hat und beide Oberklassen eine Methode namens M? Welche Methode und damit welche Implementierung (die ja unterschiedlich sein können) wird geerbt? Diesen Konflikt bei der Mehrfachvererbung kann man auf unterschiedliche Weise lösen. Manche Systeme zwingen den Benutzer in einem solchen Fall, sich für eine Implementierung zu entscheiden und diese schon bei der Klassendefinition anzugeben. Andere Systeme erlauben eine Rangordnung unter den Oberklassen. Die Oberklasse, die in der Liste der Oberklassen vorne steht, ``darf'' ihre Implementierung vererben. Andere Systeme wiederum verbieten die Definition einer solchen Klasse, bei der dieser Konflikt auftritt, und zwingen den Benutzer dazu, in einer der Oberklassen die Methode umzubenennen.

Fazit

Dadurch, daß objektorientierte Datenbanksysteme zwei Ursprünge haben, bieten die zugrundeliegenden Modelle eine Vielzahl an Konzepten, die eine realitätsnahe Modellierung vieler Anwendungen ermöglichen. Die Vielzahl an Konzepten fordert aber auch ihre Unterstützung, das heißt, es müssen zusätzliche Operationen definiert werden, Optimierungsstrategien für diese Operationen entwickelt werden, Anfragesprachen angepaßt werden usw. Insgesamt aber werden die Problembereiche relationaler Datenmodelle in objektorientierten Modellen recht gut behoben.

Systeme

Im Boom der Objektorientierung entstanden und entstehen eine Reihe von kommerziellen objektorientierten Datenbanksystemen. Da diese aber begleitend zur Entwicklung der objektorientierten Datenbankmodelle angeboten wurden und werden, können sie gar nicht alle vorgestellten Konzepte unterstützen. Neben den kommerziellen Systemen gibt es eine Reihe von interessanten Forschungsprototypen, die aber im Folgenden nicht näher betrachtet werden.

Zu den heute wohl am meisten eingesetzten kommerziellen Systemen zählen ObjectStore, O2, GemStone und ONTOS . Weitere Systeme sind ITASCA , OpenODB, POET , VERSANT und Objectivity.

ObjectStore entstammt aus der Entwicklung objektorientierter Programmiersprachen und ist sehr eng an C++ angelehnt. So können aus C- und C++-Programmen heraus entsprechende Bibliotheksfunktionen aufgerufen werden, oder man kann die DML , eine C++-Erweiterung, für Anfrageausdrücke usw. benutzen. Verfügbar ist ObjectStore unter UNIX auf diversen Workstations und unter MS-Windows auf PCs.

O2 entstammt einem Datenbanksystem, das um objektorientierte Konzepte erweitert wurde. Ein Prototyp von O2 wurde von einer Forschungsgruppe bei ALTAIR entwickelt, das endgültige Produkt wird von O2 Technology vertrieben. O2 bietet Schnittstellen zu C und C++, hat eine eigene Programmiersprache O2C, eine SQL -Erweiterung als Anfragesprache und einen Generator für graphische Benutzerschnittstellen. Das System läuft unter einer Client-Server-Architektur auf UNIX -Workstations.

GemStone wurde auf SMALLTALK -Basis entwickelt und ist damit eine Entwicklung aus der Linie der objektorientierten Programmiersprachen. Zur Schemadefinition und Datenmanipulation wird eine SMALLTALK -ähnliche Sprache namens OPAL benutzt. Da GemStone auf SMALLTALK beruht, sind Klassen und Methoden selbst wieder Objekte auf der Metaebene. GemStone wird für verschiedene Workstation-Plattformen (Sun, DEC , IBM ) als Server und Client angeboten.

ONTOS ist ebenfalls auf verschiedenen UNIX -Workstations und unter OS/2 verfügbar. Es basiert auf C++ und hat eine Client-Server-Architektur. Eine Datenbank kann hier sogar über mehrere Server verteilt sein. C++ ist auch die einzige Programmiersprachenschnittstelle von ONTOS .

Von den anderen, oben genannten Datenbanksystemen zählen ITASCA und OpenODB zu der Linie von Entwicklungen von Datenbanksystemen mit objektorientierten Konzepten. OpenODB läuft auf HP-, ITASCA auf diversen UNIX -Workstations. POET , VERSANT und Objectivity sind alle durch die Erweiterung von C++ um Datenbankkonzepte entstanden. POET wurde für PCs unter MS-Windows entwickelt, VERSANT läuft auf vielen UNIX -Workstations und Objectivity nur auf DEC stations.

Neben diesen gibt es noch einige weitere Systeme, so daß dem Anwender eine große Auswahl an Systemen zur Verfügung steht. Da alle Systeme aber recht neu sind, weisen sie noch oft ``Kinderkrankheiten'' auf. Es bleibt also zu hoffen, daß die Systeme in ein paar Jahren diese Mängel abgelegt haben, möglichst alle Konzepte objektorientierter Datenbanken unterstützen und eine einfache Möglichkeit bieten, die vorhandenen Daten aus ihrer jetzigen Speicherform zu übernehmen.

Literaturangaben

[ABD+89] M. Atkinson, F. Bancilhon, D. DeWitt, K. Dittrich, D. Maier und S. Zdonik ``The object-oriented database system Manifesto'' Proceedings of the 1st International Conference on Deductive and Object-Oriented Databases, Kyoto, Seiten 40-57, 1989.

[Bee89] C. Beeri ``Formal models for object-oriented databases'' Proceedings of the 1st International Conference on Deductive and Object-Oriented Databases, Kyoto, Seiten 370-395, 1989.

[Bee90] C. Beeri ``A formal approach to object-oriented databases'' Data and Knowledge Engineering, 5(4): 353-382, 1990.

[Dit86] K.R. Dittrich ``Object-oriented database systems: The notion and the issues'' Proceedings of the International Workshop on Object-Oriented Database Systems, 1986.

[Dit88] K.R. Dittrich (Hrsg.) ``Advances in Object-Oriented Database Systems'' Lecture Notes in Computer Science, Band 334, Springer-Verlag, 1988.

[DK89] K.R. Dittrich, A.M. Kotz Objektorientierte Datenbanksysteme, HDM -- Handbuch der modernen Datenverarbeitung 26(145): 94-105, 1989.

[Heu92] A. Heuer Objektorientierte Datenbanken Addison-Wesley, 1992.