Integration relationaler Datenbanken in objektorientierte Anwendungen Es geht auch zweigleisig in eine neue Software-Umgebung

17.03.1995

Von Werner Achtert*

Die Hersteller objektorientierter Datenbanken preisen ihre Systeme oftmals als die einzige und ideale Loesung zur Datenhaltung an. Viele Unternehmen muessen jedoch auf relationale Datenbanken zurueckgreifen. Dabei ergeben sich eine Reihe von Problemen durch die Integration von relationalen und objektorientierten Strukturen.

Viele Unternehmen stehen derzeit an der Schwelle zur Objektorientierung. Die Umstellung ist tiefgreifend: Sie bringt neue Analyse- und Designmethoden, neue Programmiersprachen und neue Datenbanken mit sich.

Im Idealfall wird die gesamte Systemumgebung auf objektorientierte Werkzeuge umgestellt. Bei Analyse- und Designmethoden sowie den Programmiersprachen kann eine Umstellung dadurch erfolgen, dass man ab einem festgelegten Zeitpunkt nur noch objektorientierte Techniken benutzt. Objekt- und funktionsorientierte Programme lassen sich prinzipiell nebeneinander benutzen.

Bei der Umstellung der Datenbasis ergeben sich erheblich groessere Probleme. Wenn eine Datenbank Informationen fuer eine integrierte Anwendung mit mehreren eigenstaendigen Bestandteilen verwalten muss, dann muessen unter Umstaenden objekt- und funktionsorientierte Anwendungen auf die gleiche Datenbasis zugreifen. Objektorientierte Programme wollen komplexe Objekte in einer Datenbank speichern, waehrend funktionsorientierte Anwendungen die Datenbank als Ansammlung von Datensaetzen in Tabellen ansehen.

Keine ploetzliche Umstellung

Da ein Unternehmen nicht alle Anwendungen zu einem Zeitpunkt auf objektorientierte Entwicklung umstellen kann, gibt es meist einen mehr oder weniger grossen Zeitraum, in dem objekt- und funktionsorientierte Programme nebeneinander zum Einsatz kommen. Weil letztere im Normalfall nicht auf objektorientierte Datenbanken zugreifen koennen, bleibt als einzige Moeglichkeit fuer eine gemeinsame Datenbasis die Benutzung eines relationalen Pendants.

Die Integration relationaler Datenbanken in objektorientierte Anwendungen setzt voraus, dass eine Verbindung zwischen den unterschiedlichen Strukturen hergestellt wird.

Eine OO-Anwendung ist in Klassen strukturiert, von denen Instanzen fuer Objekte gebildet werden. Zu einer Klasse gehoeren Attribute zur Speicherung von Daten sowie Methoden zur Bearbeitung von Objekten. Zwischen den Klassen koennen Beziehungen bestehen. Das heisst, Objekte stehen in logischer Abhaengigkeit.

Objektorientierte Daten relational gespeichert

Zur Strukturierung einer relationalen Datenbank wird ein Relationenschema benutzt, das aus Tabellen besteht. Eine Tabelle ist aufgebaut aus Datenfeldern, ein Datensatz ist ein Tupel mit konkreten Werten fuer die verschiedenen Attribute.

Um die Daten einer OO-Anwendung in einer relationalen Datenbank zu speichern, sind daher Abbildungen von Klassen auf Relationen, von Objekten auf Datensaetze und von Beziehungen noetig.

Relationen einer relationalen Datenbank koennen Saetze mit Datenwerten verwalten. Die Datenelemente einer Klasse lassen sich daher auf die Datenfelder von Relationen abbilden. Im einfachsten Fall wird dabei eine Klasse auf eine Relation abgebildet. Dies wirft jedoch dann Probleme auf, wenn eine Klasse komplexe Datenelemente wie Listen, Mengen oder Objekte anderer Klassen enthaelt. Da sich solche Strukturen nicht mit normalisierten Relationen abbilden lassen, muessen in solchen Faellen mehrere Relationen zur Darstellung einer Klasse benutzt werden.

Eine zentrale Rolle bei der Bildung von Relationen spielt die Normalisierung. Es ist in der Praxis durchaus strittig, ob Datenbankstrukturen in jedem Fall in dritte Normalform gebracht werden muessen. Gerade bei der Abbildung von Klassen kann es aus Gruenden der Uebersichtlichkeit durchaus sinnvoll sein, eine zu starke Zerlegung in Relationen zu vermeiden, da OO-Anwendungen ohnehin nur auf Objekte als Einheit zugreifen.

Die Objekte, die in einer Anwendung bearbeitet werden, sind in einer relationalen Datenbank als Saetze darzustellen. Diese Abbildung kann sich nur auf die Datenanteile der Objekte beziehen, die anderen Eigenschaften, die sich aus der objektorientierten Struktur ergeben, lassen sich in einer relationalen Datenbank nicht direkt abbilden.

Die Abbildung auf Datensaetze ergibt sich zum grossen Teil aus der Abbildung auf Relationen. Neben der Festlegung, auf welche Tabellen eine Klasse abgebildet werden soll, ist zu definieren, auf wie viele Datensaetze in diesen Tabellen ein einzelnes Objekt verteilt werden soll. Ausserdem muss eine Zuordnung von Datenelementen der Klasse zu Feldern von Relationen erfolgen.

Beispiel: Eine Klasse "Person" enthaelt neben Name und Geburtsdatum mehrere Anschriften, wobei deren Anzahl moeglichst flexibel sein soll. Die Klasse "Person" soll abgebildet werden auf zwei Relationen: "PERSON-DATEN" und "ANSCHRIFT". Die Abbildung auf Datensaetze legt fest, dass jedes Objekt der Klasse "Person" auf einen Satz der Relation "PERSON-DATEN" und mindestens einen Satz der Relation "ANSCHRIFT" abgebildet wird.

Zwischen den Objekten einer Anwendung existieren Beziehungen, die im objektorientierten Design definiert sind. In Programmen koennen Referenzen oder Zeiger solche Beziehungen ausdruecken. In einer relationalen Datenbank ist der Aufbau von Fremdschluesseln die einzige Moeglichkeit zur Darstellung von Beziehungen, das heisst, eine Relation enthaelt als Datenfeld den Primaerschluessel einer anderen Relation.

Zu jeder Klasse muss es zunaechst eine Hauptrelation geben, in der ein Primaerschluessel zur Identifizierung der Objekte der Klasse definiert ist (zum Beispiel Personalnummer in der Relation "PERSON-DATEN"). Ueber diesen Schluessel lassen sich Verbindungen zu anderen Relationen herstellen, die zur gleichen Klasse gehoeren, zum Beispiel als Fremdschluessel in der Relation "ANSCHRIFT". Damit lassen sich die Daten einer Klasse auf mehrere Relationen verteilen; ueber den Primaerschluessel der Hauptrelation sind Objekte als Einheit rekonstruierbar.

Den Primaerschluessel der Hauptrelation kann man jedoch auch zur Darstellung von Beziehungen zu anderen Klassen nutzen. So enthaelt die Relation "FAHRZEUG" als Fremdschluessel die Personalnummer des Besitzers. Auf diese Weise lassen sich Assoziationen und Aggregationen zwischen Klassen ausdruecken.

Ein wichtiges Mittel zum Strukturieren objektorientierter Anwendungen ist die Vererbung. Diese Beziehung zwischen einer Basisklasse und einer abgeleiteten Klasse laesst sich in relationalen Datenbanken nicht direkt darstellen; sie ist ebenfalls ueber Fremdschluesselbeziehungen zu realisieren, zum Beispiel die Personalnummer als Fremdschluessel in der Relation "MITARBEITER". Damit enthaelt jeder Datensatz der abgeleiteten Klasse einen Verweis auf einen Datensatz der Basisklasse. Auf diese Weise lassen sich alle Beziehungen zwischen Klassen ueber Fremdschluesselbeziehungen darstellen.

Die Integration einer relationalen Datenbank in eine OO-Anwendung verlangt es, Klassen und Objekte auf Relationen abzubilden. Damit ist jedoch nur der Zugriff mittels relationaler Operationen moeglich (Selektion, Projektion, Join). Um den direkten Zugriff auf komplette Objekte zu ermoeglichen, gilt es, zwecks Verbindung zwischen objektorientierten und relationalen Strukturen eine Schnittstelle zu implementieren. Im Idealfall kann eine Anwendung ueber diese Schnittstelle wie auf eine objektorientierte Datenbank zugreifen.

Die Bedeutung einer Funktions-Schnittstelle

Um einen einheitlichen Zugriff fuer alle Klassen zu ermoeglichen, sollte die gesamte Funktionalitaet zum Datenbankzugriff zentral zusammengefasst sein. Damit laesst sich auch ein spaeterer Umstieg auf eine andere Datenbank leichter durchfuehren.

Eine Moeglichkeit zur Realisierung eines Datenbank-Interfaces ist die Implementierung einer Funktions-Schnittstelle, ueber deren Funktionen der objektorientierte Zugriff auf die Datenbank moeglich ist. Es sind mindestens Funktionen fuer die Definition einer Klasse, das Neuanlegen, die Auswahl und das Loeschen eines Objekts zur Verfuegung zu stellen. Die so festgelegten Funktionen muessen auf Objekte zugreifen beziehungsweise solche als Ergebnis liefern.

Eine weitere Moeglichkeit ist die Kapselung der Zugriffsfunktionalitaet in einer persistenten Basisklasse. Persistenz bedeutet, dass der Inhalt von Variablen nach Beendigung eines Programms erhalten bleibt und beim naechsten Start automatisch wieder zur Verfuegung steht. Dazu muessen alle Objekte innerhalb eines Programms automatisch in einer Datenbank gespeichert werden. Die dazu noetige Funktionalitaet laesst sich in Form von Methoden in einer abstrakten Basisklasse definieren. Die Methoden muessen die gleichen Aufgaben erfuellen wie die erwaehnte Funktions-Schnittstelle. Der Zugriff auf die relationale Datenbank erfolgt allerdings dadurch, dass Anwendungsklassen von der persistenten Basisklasse abgeleitet werden und damit die Methoden zum Datenbankzugriff erben.

Die Integration einer relationalen Datenbank in eine OO-Anwendung ist damit grundsaetzlich moeglich und je nach dem gesamten Umfeld einer Anwendung auch durchaus sinnvoll. Auf jeden Fall sollte man bei einer solchen Integration eine moeglichst schmale Schnittstelle zwischen den objektorientierten Klassen- und den relationalen Datenbankstrukturen definieren, zum Beispiel in Form einer persistenten Basisklasse. Nur so sind eine langfristige Pflegbarkeit und ein spaeterer Umstieg auf eine OO-Datenbank mit vertretbarem Aufwand moeglich.