Advanced Information Management Prototype
Datenbankmanagementsystem (DBMS)
From Wikipedia, the free encyclopedia
Der Advanced Information Management Prototype (AIM-P) war ein experimentelles Datenbankmanagementsystem (DBMS), das am Wissenschaftlichen Zentrum Heidelberg (WZH) der IBM von 1982 bis 1989 entwickelt und erprobt wurde[1][2]. Der Entwurf, die Entwicklung sowie der anschließende Einsatz von AIM-P in technisch-wissenschaftlichen Anwendungsprojekten diente als „Proof of Concept“ für wesentliche Teile des am WZH entwickelten Datenmodells der „Erweiterten NF2-Relationen" (eNF2-Relationen), der darauf abgestimmten SQL-ähnlichen Anfragesprache HDBL, den benutzerdefinierten Datentypen und Funktionen, der Programmierschnittstelle zur Anwendungsentwicklung (API), der Unterstützung temporaler Daten sowie dem neuartigen Ansatz für das kooperative Zusammenwirken von (CAx-)Workstations mit Datenbankservern („Workstation-Server-Kooperation“). Die Bezeichnung „Prototype“ diente der Klarstellung, dass es sich nicht um ein kommerzielles Produkt von IBM handelt, sondern eine experimentelle Implementierung eines DBMS zur Erprobung dieser technologischen Konzepte. Die entstandenen Publikationen zeigen allerdings, dass die erarbeiteten Konzepte im Prinzip „produkttauglich“ sein sollten, wie z. B. internen Datenstrukturen für die eNF2-Relationen zum effizienten Zugriff sowohl auf ein eNF2-Objekt als Ganzes als auch auf dessen Teile[3][4][5] und die tief im Systemkern verankerte Unterstützung der Zeitversionen[6][7].
Am Entwurf und der Implementierung von AIM-P arbeiteten neben den WZH-Wissenschaftlern viele Gastwissenschaftler aus Deutschland, Europa und den USA sowie in Form von institutionellen Forschungskooperationen mit den Universitäten Darmstadt, der Fernuniversität in Hagen sowie der Universität Karlsruhe (dem heutigen KIT) mit. Dies spiegelt sich auch in den ca. 70 wissenschaftlichen Publikationen von Projektmitgliedern wider, die während ihrer Mitarbeit beim Entwurf, der Implementierung, der Entwicklung weiterer Konzepte und der Evaluation des AIM-P-System entstanden sind. Das AIM-P-Forschungs- und Entwicklungsprojekt (insbesondere der NF2-/eNF2-Ansatz) inspirierte weltweit zahlreiche Forschungsaktivitäten (wie z. B. in Australien[8], Finnland[9][10], Frankreich[11][12], Italien[13], Japan[14], Kanada[15], Niederlande[16][17] und den USA[18][19][20]). Teile des NF2-/eNF2-Ansatzes wurden später auch in kommerzielle relationale DBMS integriert (wie z. B. 1997 in Oracle Version 8[21] und 1999 in Informix Dynamic Server.2000[22]) und gingen z.T. auch in den SQL-Standard ab SQL:2003[23] ein, allerdings in einer im Vergleich zum AIM-P-Ansatz stark eingeschränkten Form.
Vorgeschichte
Ende der 1970er Jahre – also noch bevor die ersten kommerziellen relationalen DBMS auf den Markt kamen – experimentierten Wissenschaftler am IBM Research Laboratory in San Jose (dem späteren IBM Almaden Research Center) und am Wissenschaftlichen Zentrum Heidelberg der IBM mit den Einsatz von System R in Anwendungen, in denen komplex strukturierte Datenobjekte zu verwalten waren. In San Jose waren dies ingenieurwissenschaftliche[24], während es in Heidelberg Dokumentenretrieval-Anwendungen[1][25] waren. Beide Gruppen kamen unabhängig von einander zu dem Ergebnis, dass auf dem Relationmodell von E.F. Codd basierende Datenbanksysteme mit ihren (wegen der 1. Normalform) „flachen“ Relationen (im Folgenden „1NF-Relationen“ genannt) für Anwendungen dieser Art nicht geeignet sein werden.
Während man im San Jose Resarch Lab der IBM (dem späteren IBM Almaden Research Center) 1NF-Relationen ausgerichteten DBMS-Kern nicht anrührte und es mit einem „On-Top“-Ansatz versuchte[24], erweiterte man am WZH die theoretische Grundlage des relationalen Datenmodells und die zugrundeliegende Relationenalgebra, so dass diese auch Relationen mit relationswertigen Attributen („geschachtelte Relationen“), unterstützen konnte. Da dieses erweiterte relationale Datenmodell die Forderung der ersten Normalform (1NF) aufgibt, nannte man es Non First Normal Form Relations (abgekürzt NF2-Relationen)[26] und skizzierte auch einen Sprachvorschlag zur Erweiterung der Datenbank-Anfragesprache SQL[25].
Nachdem diese Schwächen der in Entwicklung befindenden relationalen DBMS erkannt wurden, richtete man Ende der 1970er Jahre am WZH den Forschungsbereich „Advanced Information Management“ (AIM) ein, um dort die Anforderungen an zukünftige Datenbanksysteme in neuen Anwendungsbereichen systematisch zu untersuchen und hierfür ggf. geeignete (und bei Bedarf auch über den NF2-Ansatz hinausgehende) Lösungskonzepte zu entwickeln[1][2]. Zu Anfang wurden eine ganze Reihe von „Nicht-Standard“-Datenbankanwendungen, wie z. B. Computer Integrated Manufacturing (CIM), Computer Aided Design (CAD), Robotik, Geoinformationssysteme, Dokumenten-Verwaltung (Dokumenten-Retrieval), untersucht, um ihre Anforderungen an die benötigten Datenstrukturen und Datentypen, die Art der Anfragen und die daraus resultierenden Anforderungen an das DBMS zu ermitteln[27].
Die hierbei gewonnen Erkenntnisse ließen erkennen, dass auch das NF2-Relationenmodell nicht alle Anforderungen abdecken kann, sondern dass ein noch mächtigeres Datenmodell, eine dazu passende Anfragesprache sowie die Unterstützung benutzerdefinierter Datentypen und Operationen benötigt werden. Außerdem sollten geeignete Konzepte für das Zusammenwirken von CAx-Workstations mit Datenbankservern („Workstation-Server-Kooperation“) sowie die Unterstützung zeitversionierter Daten (im Sinne einer temporalen Datenbank) erarbeitet werden[27].
System-Architektur
Ende 1982 wurde dann am WZH entschieden einen DBMS-Prototyp zu bauen, in dessen sowie Entwurf und Implementierung alle wesentlichen Erkenntnisse einfließen sollten, die sich im Verlauf des Projektes ergeben, so dass diese nach Fertigstellung dieses DBMS in realitätsnahen Anwendungsszenarien als Proof of Concept erprobt werden können. Dieser Prototyp erhielt den Namen „Advanced Information Management Prototype (AIM-P)“[1][28] und seine Anfragesprache den Namen bzw. das Akronym HDBL ("Heidelberg Database Language). Seine Architektur mit den wichtigsten Komponenten ist in Abb. 1 dargestellt.

Der Query Processor nimmt die in HDBL formulierten Anfrage- und Änderungsoperationen entgegen. Er hat eine logische Sicht auf das eNF2-Datenmodell, das in etwa der bildlichen Darstellung als geschachtelte Tabellen (wie weiter unten abgebildet) entspricht. Er übersetzt jeden HDBL-Ausdruck in einen Operatorbaum in dem, ggf. (auch tief) geschachelt, die mit Aufrufparametern versehenen Operatoren der HDBL-Algebra für Selektion, Projektion usw. eingebettet sind. (Wenn nur 1NF-Relationen involviert sind, sieht dieser sehr ähnlich aus wie der vom Anfrageoptimierer eines relationalen DBMS erzeugte.) Diesen Operatorbaum reicht der Query Processor an den Complex Object Manager weiter, der die Operatoren der HDBL-Algebra durch die konkreten Such- und Zugriffsoperatoren auf die benötigten Datensätzen der intern verwendeten Speicherstrukturen ersetzt und im Folgenden auch die weitere Ausführung der erzeugten Anfrage- und Änderungsoperationen steuert. Für das Lesen und ggf. Einfügen, Löschen und Ändern aller dieser Datensätze ruft der Complex Object Manager den Subtuple Manager auf und versorgt diesen mit der Information, in welchem Transaktionsmodus ("read-only" oder "update") im Falle einer neuen Transaktion diese ausgeführt werden soll. Der Subtuple Manager kümmert sich auch um die zeitversionierte Speicherung der Datensätze, den Zugriff auf historische Versionen, das transaktionsorientierte Logging und Recovery sowie das Setzen und Freigeben von Sperren. Hierauf wird im Abschnitt "System-interne Aspekte" näher eingegangen.
Konventionelle relationale DBMS und das „Complex Object“-Problem
Für die „vor-relationalen“ DBMS, die auf dem hierarchischen Datenbankmodell oder dem Netzwerk-Datenbankmodell basieren ist typisch, dass man sich das gewünschte Anfrageergebnis in der Regel mit Folgen von einzelnen DatenbankAnfragen quasi stückweise zusammensuchen muss. (Ausführliche Anfragebeispiele zu diesen DBMS finden sich z. B. in[29] und[30].) Im Gegensatz dazu ermöglichen relationale DBMS, solche DatenbankAnfragen mit einem einzigen Anfrageausdruck zu erledigen. Ermöglicht wird dies durch die diesem Datenmodell zugrundeliegende Relationenalgebra bzw. die darauf aufbauende Anfragesprache SQL. Die Relationenalgebra setzt voraus, dass alle Daten als 1NF-Relationen gespeichert werden.
Bei relativ einfach strukturierten Daten, wie sie z. B. im kaufmännischen Bereich vorkommen, funktionieren deren Abbildung auf 1NF-Relationen sowie DatenbankAnfragen gegen diese in der Regel recht gut. Ganz anders sieht es hingegen bei großen und komplex-strukturierten Datenobjekten aus, wie sie z. B. bei CAD-Konstruktionsdaten von Motoren, Turbinen, PKW, Flugzeugen und Gebäuden auftreten. Betrachten wir als (stark vereinfachtes) Beispiel[31] die Speicherung der Daten von Robotern, wie in Abb. 2 illustriert (den Gelenken sind sog. DH-Matrizen zugeordnet, die zur Berechnung von Bewegungsabläufen benötigt werden). Für die Abbildung all dieser Daten würde man in einem relationalen DBMS etwa die in Abb. 3 dargestellten 1NF-Relationen verwenden.


Eine typische Datenbankanfrage wäre alle Informationen zu einem bestimmten Roboter zu erhalten. Dies würde z. B. die in Abb. 4 dargestellte SQL-Anweisung leisten und als Resultatmenge die in Abb. 5 skizzierte Ergebnistabelle zurück liefern.


Durch die 1NF-Ergebnisdarstellung (und nur diese gibt es in relationalen DBMS) erhält man eine Tabelle, in der sich die vom Anwender gewünschte Information über viele Spalten und Zeilen verstreut und so eigentlich für ihn nicht direkt brauchbar ist. Um mit diesen Ergebnisdaten etwas anfangen zu können, müssen diese deshalb per Anwendungsprogramm erst in eine strukturierte, lesbare Form gebracht werden. Bei realen Daten für Roboter-Anwendungen, bei den CAD-Daten für einen Serien-PKW mit all seinen Varianten, bei einem Flugzeug usw. können dies hunderte und auch tausende von 1NF-Relationen sein. Anfragen dieser Art würden dann in vielen Fällen zu extrem großen Resultattabellen mit vielen hundert oder gar tausend Spalten führen (was die relationalen DBMS des Jahrgangs 1983 überhaupt nicht unterstützt hätten). Abgesehen davon würde es auch zu tausenden von Zeilen führen, was sich wiederum in sehr langen Antwortzeiten niederschlagen würde. Die „Lösung“ sah deshalb Mitte der 1980er Jahre – und das hat sich bis heute (2026) eigentlich nicht wesentlich geändert – dann wie in Abb. 6 skizziert aus. Das Anwendungsprogramm oder eine Zwischenschicht zwischen diesem und der Datenbank führt, mehrfach iterierend, viele einzelne SQL-Anfragen auf der relationalen Datenbank aus, wobei der „Output“ einer Anfrage in der Regel den „Input“ für die nachfolgende Anfrage liefert. Bei dieser Vorgehensweise werden die benötigten Daten quasi „stückweise“ aus der Datenbank geholt. Diese Art der Interaktion zwischen Anwendungsprogramm und Datenbanksystem ähnelt damit stark derjenigen bei den DBMS aus der vor-relationalen Zeit, die auf dem hierarchischen oder Netzwerk-Datenbankmodell basierten.

Das 1NF-Datenmodell hat darüber hinaus auch noch eine weitere Schwäche: Es bietet – insbesondere im Kontext komplex strukturierter Datenobjekte – dem Anwendungsentwickler keine intuitive Vorstellung, wie das komplexe Datenobjekt strukturiert ist. Da dieses aufgrund der Normalisierung auf viele Relationen verteilt gespeichert werden muss, benötigt dieser deshalb in den meisten Fällen jeweils ein geeignetes semantisches Datenmodell (wie z. B. ER- oder UML-Diagramme) als Hilfsmittel, um die SQL-Anfrage überhaupt so formulieren zu können, dass sie das gewünschte Ergebnis liefert.
NF2- und eNF2-Relationenmodell
NF2-Relationenmodell
Wie im Abschnitt „Vorgeschichte“ erwähnt, waren das am WZH entwickelte NF2-Relationenmodell[26] in Verbindung mit Sprachvorschlägen für eine dazu passende SQL-ähnliche Anfragesprache[25][32], bereits ein wichtiger Schritt zur besseren Unterstützung komplex strukturierter Datenobjekte. Die Roboterdaten könnten in diesem Relationenmodell z. B. wie in Abb. 7 illustriert strukturiert werden.

Das NF2-Relationenmodell
- ist eine Verallgemeinerung des 1NF-Relationenmodells, d.h. jede korrekt konstruierte 1NF-Relation ist auch eine korrekt konstruierte NF2-Relation[26][33]
- ermöglicht eine natürlichere und intuitiv besser verständliche Darstellung hierarchisch strukturierter Objekte (siehe Abb. 7)[9][34]
- ermöglicht die kompakte Übertragung solcher Anfrageeergebnisse zum Anwendungsprogramm oder zur Workstation[35][36][37] und reduziert dort ggf. den Aufbereitungsaufwand
- basiert auf einer (erweiterten) Relationenalgebra und ermöglich hierdurch auch (weiterhin) eine systemseitige Anfrageoptimierung[33][38][39][40]
- verfügt über entsprechend angepasste Normalformen für den Datenbankentwurf[41][42]
Wenn ein NF2-DBMS Sichten unterstützt, dann ergeben sich hinsichtlich der in Abb. 7 dargestellten NF2-Tabelle im Prinzip zwei Möglichkeiten der internen Speicherung:
- Speicherung als strukturiertes NF2-Datenobjekt (d.h. als Tupel einer NF2-Relation) mit darauf zugeschnittenen internen Datenstrukturen[5][4]
- Speicherung als 1NF-Relationen (wie in Abb. 3) und man definiert darauf eine der Abb. 7 entsprechende Sicht
Da die 1NF-Relationen in diesem Beispiel verlustfrei in die NF2-Darstellung und umgekehrt transformiert werden können, könnte man bei Realisierungsvariante 1 umgekehrt auch die 1NF-Relationen als Sichten auf die gespeicherte NF2-Relation realisieren und über beide Wege dann auch Änderungsoperationen (Updates) unterstützen.[33]
eNF2-Relationenmodell
Das NF2-Relationenmodell stellt zwar für technisch-wissenschaftliche Anwendungen bereits einen wichtigen Schritt in die richtige Richtung dar, ist aber hinsichtlich der Vielfalt der Datenstrukturen, die in solchen Anwendungen benötigt werden[43][44][45], bei weitem noch nicht ausreichend. Die Entwicklung vom NF2 zum endgültigen "erweiterten NF2-Relationenmodell (kurz: eNF2-Relationenmodell) war ein iterativer Prozess verbunden mit sukzessiven Erweiterungen des NF2-Ansatzes um weitere Konstrukte wie Liste von atomaren Werten, Liste von Tupeln, Listen von Listen usw. (Eine ausführliche Begründung dieser Erweiterungen mit Anwendungsbeispielen findet sich in[31].) Das finale eNF2-Relationenmodell war auch stark von den bei dem Entwurf der dazu passenden Datenbankanfragesprache gewonnenen Einsichten geprägt (siehe Abschnitt Anfragesprache (HDBL)) und kennt nur noch atomare Werte sowie die Konstruktoren Tupel, Liste und (Multi-)Set, die alleine stehen oder in beliebiger Weise miteinander kombiniert werden können, wie in Abb. 8 illustriert. Jedes so erzeugte Objekt ist ein strukturell legales Objekt des eNF2-Relationenmodells. Es kann als Ergebnisobjekt in Anfragen und in Zwischenergebnissen von geschachtelten Anfrageausdrücken auftreten und auch in einer eNF2-Datenbank gespeichert werden[27]. - Die für das eNF2-Relationenmodell entwickelte Relationenalgebra[28][27] (die leider nie in Gänze publiziert wurde), ermöglicht ebenfalls eine systemseitige Anfrageoptimierung, ist naturgemäß jedoch komplexer als bei 1NF-Relationen.[46][28]

Bei Verwendung des eNF2-Relationenmodells kann man z. B. auf das in Abb. 7 noch vorkommende „Sortier-Attribut“ 'AxisNo' verzichten und die DH-Matrix als Liste von Listen von atomaren Werten darstellen wie in Abb. 9 illustriert (und wenn man 'Arms' als Liste speichern würde, wäre auch das Attribut 'ArmID' überflüssig.)

Anfragesprache (HDBL)
Vorbemerkungen
Die bahnbrechende Neuerung bei der Entwicklung des relationalen Datenmodells durch E.F. Codd[47] war die konsequente Speicherung aller Daten als Relationen mit 1NF-Tupeln als Datensätzen und die darauf aufbauende Definition der Relationenalgebra mit Operatoren wie Selection, Projection, Join usw. Diese Operatoren haben allesamt die Eigenschaft, dass sie, angewandt auf eine 1NF-Relation, als Ergebnis stets wieder eine 1NF-Relation zurückgeben. Durch diese Orthogonalitäts-Eigenschaft kann man auch sehr komplexe, geschachtelte Anfrageausdrücke mit diesen Operatoren formulieren. Außerdem kann man – in Analogie zur mathematischen Algebra – Äquivalenztransformationen definieren, die es ermöglichen einen Anfrageausdruck in einen anderen Anfrageausdruck umzuformen, der – angewandt auf dieselben Ausgangsrelationen – zum selben Ergebnis führt. (Die Reihenfolge der Tupel sowie der Attribute der Ergebnisrelationen werden hierbei as irrelevant betrachtet.) Diese Äquivalenztransformationen ermöglichen die Implementierung von Anfrageoptimierern in relationalen DBMS.
Alle diese Eigenschaften gelten auch für die von Jaescke und Schek entwickelte NF2-Relationenmodell mit der zugehörigen NF2-Algebra[26]. Hierzu wurden die Operatoren der 1NF-Algebra wurden – soweit erforderlich – geeignet redefiniert und zusätzlich die Operatoren 'nest' („schachteln“) und 'unnest' („entschachteln“) eingeführt, um 1NF-Relationen in NF2-Relationen und umgekehrt zu transformieren. Das 1NF-Relationenmodell ist hierdurch ein Spezialfall des NF2-Relationenmodells und damit ist jede 1NF-Relation auch eine NF2-Relation. D.h. die Orthogonalitäts-Eigenschaft ist auch hier gegeben.
Die in den relationalen DBMS verwendete Datenbankanfragesprache SQL wird intern zwar auf die Operationen der 1NF-Relationenalgebra nebst einigen weiteren, wie z. B. Sortierung, Gruppierung und Join-Varianten, abgebildet, hat jedoch nicht mehr die vollständige Orthogonalitäts-Eigenschaft des 1NF-Relationenmodells. Der Sortieroperator (ORDER BY) erzeugt z. B. eine (sortierte) Liste von Tupeln, die nicht mehr dem Relationenmodell entspricht (das nur Mengen kennt) und darf daher nicht innerhalb von geschachtelten SQL-Ausdrücken auftreten. Noch weitergehend ist der Gruppierungsoperator GROUP BY von SQL, der intern eine Relation mit Untermengen (d.h. Mengen von Mengen von Tupeln) und damit eigentlich eine geschachtelte Relation à la NF2 erzeugt. Aus diesem Grund darf er stets nur in Verbindung mit Aggregations-Operatoren wie COUNT, SUM, AVG usw. verwendet werden, die jede Teilmenge jeweils auf ein einziges Tupel reduzieren, welches jeweils die aggregierten Attributwerte enthält und die Ergebnisrelation damit dann wieder 1NF-konform ist.
Das an sich sehr viel komplexere eNF2-Datenmodell hat diese Art von Problemen nicht, da all die zuvor beschriebenen nicht-1NF-konformen Zwischen- und Endzustände legale Strukturen des eNF2-Relationenmodells darstellen. Allerdings ist natürlich die Anzahl der Operatoren der eNF2-Relationenalgebra, z. B. zur Typumwandlung (Menge ↔ Liste, flach ↔ geschachtelt), Zugriff aus Listenelemente (einzeln oder von-bis-Intervalle) sowie für Änderungsoperationen ganz erheblich größer. Mehr Details hierzu finden sich in den Publikationen [48], [49], [50] und [51].
Herausforderungen und grundlegende Entwurfsentscheidungen
Bei der in Abb. 4 dargestellten SQL-Anfrage sieht man bereits, auch SQL-Anfragen recht komplex werden können. Wenn neben vielen Basistabellen auch noch weitere Operationen wie z. B. Group-By-Having, Vereinigung, Durchschnitt und Differenz erforderlich werden, kann die semantisch korrekte Formulierung der Datenbankanfrage auch für einen erfahrenen SQL-Anwender herausfordernd sein.
Bei einem sehr viel mächtigeren Datenmodell wie den eNF2-Relationen, wo neben den 1NF-Relationen im Prinzip jede Kombination von Mengen, Listen, Tupeln und atomaren Werten sowie als Basisobjekte, als Zwischenergebnisse und als Ergebnistyp auftreten können, braucht eine Anfragesprache mit klaren, leicht verständlichen Regeln sowie mit einem (möglichst vollständigen) Verzicht auf Ausnahmen und Sonderfälle, um trotz aller inhärenten Komplexität noch beherrschbar zu sein. Die für AIM-P und das eNF2-Datenmodell entwickelte Datenbankanfrage- und -manipulationssprache HDBL (ein Akronym für „Heidelberg Database Language“[27]) wurde unter Beachtung dieser Vorgaben entworfen und in wesentlichen Teilen prototypisch in AIM-P implementiert[48][49]. Das SELECT-FROM-WHERE-Konstrukt (kurz: SFW-Konstrukt) wurde z. B. einerseits beibehalten und sogar auf Listen von Tupeln erweitert, andererseits aber auch in dem Sinne „entschlackt“, dass nicht mehr jede Art von Anfrage-Operatoren der zugrundeliegenden eNF2-Relationenalgebra (wie z. B. GROUP-BY .. HAIVING bei SQL) in das SFW-Konstrukt integriert wird. Das SFW-Konstrukt wird damit ein „normaler“ Operator, der im Wesentlichen „nur noch“ für die syntaktische Repräsentation der Basis-Operatoren Selektion und Projektion von Mengen und Listen von Tupeln in HDBL zuständig ist. Das SFW-Konstrukt kann z. B. auch für die Sortierung verwendet von Mengen und Listen von Tupeln verwendet werden, man kann aber – wie im HDBL-Beispiel 3 gezeigt – die Sortierung auch durch die Anwendung des Sortier-Operators auf die (Zwischen-)Resultatmenge der SFW-Operation erhalten. Daneben gibt es noch weitere Operatoren wie z. B. für die Entfernung von Duplikaten, für die Gruppierung, für Typ-Umwandlungen und vieles andere mehr.
Es gibt auch klare Regeln welche Anfrageoperation welche Strukturtypen als Input erwartet und welchen sie als Output zurück gibt. Hierbei wird eine starke Typisierung („strong typing“) verfolgt. So kann z. B. der vorher erwähnte Sortier-Operator nur auf Listen von Objekten angewandt werden. Falls die Ausgangsdaten als Menge vorliegen, dann muss dem Sortieren eine Typwandlung Menge → Liste (mittels MLIST-Operator) vorgeschaltet werden. Wenn das SFW-Konstrukt mit der ORDER-BY-Klausel versehen ist, dann ist der Ergebnistyp immer vom Typ 'Liste', auch wenn 'Menge' der Input-Typ war.[50]
Im folgenden exemplarisch einige Anwendungsbeispiele von HDBL mit dem SELECT-FROM-WHERE-Konstrukt, die im Wesentlichen aus[31] entnommen wurden. Sehr viele weitere Beispiele, insbesondere auch zu INSERT, UPDATE und DELETE finden sich ebenfalls dort.
Anfragen mit dem SELECT-FROM-WHERE-Konstrukt
Wie bereits oben erwähnt verwendet HDBL ebenfalls das SFW-Konstrukt zur Formulierung von Selektionen und Projektionen, allerdings sowohl auf Mengen als auch auf Listen von Tupeln. In beiden Fällen können bei HDBL die Attribute der Tupel sowohl atomar als auch beliebig komplex strukturiert sein. Das SFW-Konstrukt kann in HDBL darüber hinaus auch dazu verwendet werden, um „flache“ in geschachtelte Relationen zu („Nestung“) und umkehrt („Entnestung“) zu überführen.
Beispiele:
Beispiel Q1: Anfrage auf 1NF-Relationen mit Join
Aufgabe: „Gib zu allen Robotern deren ID und Beschreibung sowie die passenden Endeffektoren mit deren und Funktion sortiert nach Roboter-ID als 'flache' Relation aus“.

Die eckigen Klammern in der SELECT-Zeile drücken explizit aus, dass das Ergebnis tupelstrukturiert sein soll. Durch die Sortierung ist der Resultattyp dieser Anfrage eine Liste von Tupeln.
Anmerkung: Die Formulierung des Joins im obigen HDBL-Beispiel entspricht der Join-Syntax gemäß SQL:1986-Standard, an dem man sich beim Entwurf von HDBL orientiert hat. Die expliziten Join-Operatoren wurden erst später mit SQL:1992 eingeführt und waren zum Zeitpunkt der Entwicklung von HDBL daher noch nicht bekannt. Die neue Join-Syntax hat die „alte“ aber nicht abgelöst, sondern stellt nur eine alternative syntaktische Formulierung einer Join-Operation dar (und könnte auch problemlols in HDBL integriert werden).
Beispiel Q2: Alternative Strukturen für das Anfrageergebnis
Aufgabe: „Gib die IDs aller Roboter aus“.

Da wir in der Anfrage keine Sortierung spezifiziert haben, würde bei der ersten Anfrage-Variante eine Menge von Tupeln mit dem Attribut RobID zurückgeliefert, also z. B. { ['Rob2'], ['Rob1'], ['Rob3'] } und bei der 2. Variante eine Menge von atomaren Werten, also z. B. { 'Rob2', 'Rob1', 'Rob3' }.
Beispiel Q3: Anfrage-Alternativen für die sortierte Ausgabe der RobIDs
Die in diesem Fall einfachste Alternative ist die Anfragen in HDBL-Beispiel 2 (Abb. 11) um die ORDER-BY-Klausel erweitern, womit man dann < ['Rob1'], ['Rob2'], ['Rob3'] > bzw. < 'Rob1', 'Rob2', 'Rob3' > als Ergebnis erhält. Eine andere Alternative ist die explizite Anwendung des ORDER-BY-Operators wie in Abb. 12 illustriert.

Beispiel Q4: Einfache Selektions-Anfragen mit Resultatstruktur wie gespeichert
Aufgabe: „Gib alle Roboter aus“ sowie „Gib alle Roboter aus, die den Endeffektor 'SR200' anschließen können“

Beispiel Q5: Ausgabe einer Relation ohne Strukturänderung, aber mit Selektion auf mengenwertigem Attribut
Aufgabe: „Gib alle Roboter aus mit allen Daten aus, ausgenommen bei den Endeffektoren, da interessieren nur die Schraubenzieher ('Screw Driver')“


Beispiel Q6: „Gib die RobotNF2-Relation aus und blende dabei die Spalten Col1..Col4 des Attributs DH_Matrix aus“


Beispiel Q7: Überführung von 1NF-Relationen in eine inhaltlich äquivalente, geschachtelte NF2-Relation
Aufgabe: „Gib auf Basis der 1NF-Relationen aus Abb. 3 eine geschachtelte NF2-Ergebnis-Relation à la RobotsNF2 aus Abb. 7 aus“

Beispiel Q8: Erstellung einer geschachtelten eNF2-Relation mit listenwertigen Attributen auf verschiedenen Ebenen
Aufgabe: „Gib auf Basis der 1NF-Relationen aus Abb. 3 eine geschachtelte eNF2-Ergebnis-Relation à la Robots_eNF2 aus Abb. 9 aus“

Zu erwähnen ist noch, dass alle diese Anfrageergebnisse auch legale Datenbankobjekte in HDBL sind und daher z. B. auch mittels INSERT-Operation in die Datenbank eingefügt werden können.
System-interne Aspekte
Speicherstrukturen für das NF2-/eNF2-Relationenmodell
Eine Motivation für die explizite Unterstützung komplexer Objekte in einem Datenbanksystem ist, dass man diese bei Bedarf als Ganzes rasch auslesen kann. Auf der Speicherungsebene bedeutet dies, dass es vorteilhaft ist, alle Teile eines solchen Objekts benachbart auf der Festplatte zu speichern. Man kann aber auch Daten, die man sehr häufig zusammen benötigt und die man im 1NF-Fall mittels Join-Operation in einer Anfrage verknüpfen würde, ebenfalls in einer passenden NF2-Struktur, quasi als „vorberechnete Joins“[39] speichern. In einem solchen Fall sollen hierdurch natürlich keine wesentlichen Nachteile entstehen, wenn man auf diese (evtl. sogar tief geschachtelten) Daten auch separat zugreifen möchte. Im AIM-P-Projekt hat man verschiedene Realisierungsvarianten evaluiert und sich dann für die folgende Vorgehensweise entschieden[4][5]: Die Datensätze für die Strukturinformation der eNF2-Objekte – in AIM-P als „Mini-Directories“ (MD) bezeichnet – werden getrennt von den Nutzdaten gespeichert. Mittels physisch benachbarter Speicherung („clusterung“) der MD-Datensätze eines eNF2-Objektes konnte man dessen Strukturinformation daher sehr effizient lesen, dort dann das gewünschte (Sub-)Objekt identifizieren und mit den – ebenfalls in den MD-Datensätzen enthaltenen Adressinformationen auf die (Nutz-)Daten dieses (Sub-)Objekts zuzugreifen. Ausführliche Beschreibungen hierzu finden sich in [4],[5] und [31].
Concurrency Control, Logging und Recovery
Concurrency Control sowie Logging und Recovery sind systemseitige Maßnahmen zur Synchronisation konkurrierend ausgeführten Transaktionen sowie zur Gewährleistung der Konsistenz der Datenbank in Normalbetrieb sowie auch im Falle von ungeplanten Transaktionsabbrüchen infolge von Systemzusammenbrüchen, Stromausfall und anderen Ereignissen. Die grundlegenden Prinzipien wie Sperrverfahren (mit Zweiphasen-Sperrprotokoll und verschiedenen Sperrmodi), wurden bereits Ende der 1970er und Anfang der 1980er Jahre im Rahmen des Projektes IBM System R [52][53] publiziert, so dass man bei der Entwicklung von AIM-P darauf aufsetzen und für die eigenen Anforderungen anpassen und weiterentwickeln konnte. Hierzu gehörten u.a.
- Sperrverfahren für komplex-strukturierte Objekte [54][55]
- Sperr- und Update-Verfahren für Text-Indexe [56]
Ansonsten galt auch für AIM-P, dass alle Transaktionen alle Objekte auf die sie zugreifen möchten, zuvor mit geeigneten Sperren belegen müssen, die erst nach dem Commit der Transaktion wieder freigegeben werden. Lediglich für langlaufende Transaktionen, wie sie z.B. im Kontext CAD-Anwendungen auftreten [24][57], wurde eine Erweiterung eingeführt. Die Sperren dieser Transaktionen wurden während der Laufzeit dieser Transaktion persistent gespeichert, um diese nach einem Neustart des Datenbanksystems und vor Aufnahme des normalen Transaktionsbetriebs wieder aktivieren zu können.
Das Logging, d.h. die Protokollierung von Änderungen der von Transaktionen gemachten Änderungen in der Datenbank zwecks Rückgängigmachung oder Wiederholen von diesen, das von den kontemporären Datenbanksysten im Wesentlichen nur für das Recovery verwendet wurde, wurde in Form des im nächsten Abschnitt beschriebenen Transaction-oriented Workspace so umgestaltet, dass es für viele andere Zwecke nutzbringend angewandt werden konnte.
Transaction-Oriented Workspace (TWS)
Beim Start einer Update-Transaktion wird ihr vom Subtuple-Manager ein Transaction-oriented Workspace (TWS) zugeordnet. Ein solcher TWS besteht aus einem dieser Transaktion exklusiv zugeordneter Bereich im Systempuffer sowie einem ebenfalls exklusiv zugeordnetes Datenbank-Segment auf dem Hintergrundspeicher des Datenbanksystems [58]. Der TWS nimmt alle geänderten Datensätze dieser Transaktion auf, egal ob Benutzerdaten oder Mini-Directories. Im TWS-Index wird verzeichnet, welche Datensätze sich bereits im TWS befinden. Alle Udate-Operationen laufen ebenfalls über den Subtuple-Manager und spezifieren jeweils exakt, welche Teile des Datensatzes zu ändern sind und speichert diese Information in einer Undo-Liste im TWS. Diese Liste ist sehr ähnlich zu den Undo-Logs der konventionellen Datenbanksysteme, nur dass deren Einträge zunächst nur im TWS verbleiben.
Vor dem Commit einer Update-Transaktion gelangen keinerlei Änderungen von ihr in die Datenbank. Lese-Transaktionen können während dieser Zeit - bis auf das Anfordern von Lesesperren - ungehindert auf diese Datensätze in der Datenbank zugreifen.
Wird eine Update-Transaktion vor Erreichen ihres Commit-Zeitpunkts von Seiten des Benutzers, der Anwendung oder anderer Umstände abgebrochen, dann besteht die "Recovery"-Maßnahme für diese darin, die von ihr gesetzten Sperren frei zu geben und den TWS (Systempuffer-Bereich + Datenbanksegment) zu löschen und für die weitere Verwendung wieder frei zu geben.
Erreicht eine Update-Transaktion ihren Commit-Zeitpunkt, werden folgende Aktionen durchgeführt:
- Pre-Commit-Phase: Alle geänderten Datensätze sowie deren Undio-Listen werden - soweit noch erforderlich - vom TWS-Systempuffer in dessen Datenbank-Segment geschrieben ("forced write") (damit sind alle Änderungen "in Sicherheit gebracht")
- Commit-Phase:
- Die vorher bereits gesetzten IX-Sperren (siehe Sperrverfahren) werden für die zu ändernden Datensätze in X-Sperren konvertiert
- Die Datensätze werden vom TWS-Systempuffer in den regulären Systempuffer verschoben und von dort in die Datenbank geschrieben
- Der TWS-Systempuffer-Bereich dieser Update-Transaktion wird gelöscht frei gegeben
- Die Einträge in den Undo-Listen werden bei Bedarf etwas zusammengefasst und mit den Commit-Zeitstempel versehen in den History-Pool geschrieben (siehe nächsten Abschnitt für mehr Details hierzu)
- Die für diese Transaktion gesetzten Sperren werden aufgehoben
- Sobald sichergestellt ist, dass alle geänderten und neuen Datensätze in die Datenbank und den History-Pool geschrieben wurden, kann das TWS-Datenbank-Segment gelöscht und freigegeben werden
Der TWS wird auch für lange Transaktionen genutzt, wie sie z.B. in technisch-wissenschaftlichen Entwicklungsprojekten auftreten und sich über viele Stunden, u.U. auch mehrere Tage erstrecken können. Hier ist relativ typisch, dass das zu bearbeitende komplexe Objekt (z.B. ein mittels CAD konstruiertes Fahrzeug) per "Check-out" aus der Datenbank "ausgeliehen", auf die Workstation geladen und dort bearbeitet und dann mittels "Check-in" wieder in der Datenbank gespeichert wird.[24][57] - Neben den oben bereits erwähnten persistenten Langzeit-Sperren, können lange Transaktion auch Zwischenzustände des ihres TWS auf der Workstation auf das Datenbank-Segment ihre TWS-Pendants auf dem Datenbankserver propagieren und damit Sicherungspunkte für diese Transaktion erzeugen, auf die sie bei Bedarf zurückgehen und die Bearbeitung von dort aus fortsetzen kann. (Ein solches Konzept wurde später unter der Bezeichnis "Save Points" auch in den SQL-Standard übernommen.) - Ergänzend oder alternativ dazu kann man diese Daten auch zeitversioniert (siehe nächsten Abschnitt) speichern.
Unterstützung temporaler Daten
Sowohl das Anfang der 1980er Jahre wiederauflebende Interesse in der wissenschaftlichen Welt an der Unterstützung zeitversionierter Daten in Datenbanksystemen (siehe z. B.[59][60]) als auch die eigenen Anforderungsanalysen zu Beginn des AIM-P-Projekts haben zum Entschluss geführt, die Unterstützung temporaler Daten von Anfang an beim Systementwurf mit zu berücksichtigen.[6] Besondere Anliegen hierbei waren, diese Unterstützung so zu realisieren, dass hierdurch
- der Zugriff auf die aktuellen Daten nicht verlangsamt wird
- die Speicherung der Historie in kompakter Form erfolgen kann
Diese beiden Ziele wurden durch eine Separierung der aktuellen von den historischen Daten erreicht; und zwar auf Ebene der Speicherung von Datensätzen aller Art. Es gibt zum einen die aktuellen Datensätze und einen Versions-Pool mit den historischen Daten, im AIM-P „History-Pool“ genannt. Für jeden aktuellen Datensatz, der mindestens einmal durch eine Update-Operation verändert wurde, gibt es im Index des History-Pools einen Eintrag mit seinem Datensatz-Identifier, der den Kopf einer rückwärtsverketteten Liste von zeitgestempelten History-Datensätzen repräsentiert, welche die in einer Transaktion durchgeführten Änderungen am Datensatz in kompakter Form (als "Delta") speichern. Das Wiederherstellen des historischen Zustandes eines Datensatzes wie folgt: Man beginnt mit dem aktuellen Datensatz oder – falls dieser gelöscht wurde – mit seinem letzten vollständigen Eintrag im History-Pool und macht die durchgeführten Änderungen so lange mit den Delta-Datensätzen rückgängig, bis man den gewünschten Zeitpunkt erreicht hat. Diese History-Datensätze haben eine große Ähnlichkeit zu den sog. „Undo-Log-Records“,[61] welche in den Datenbanksystemen zum Zurücksetzen von Änderung beim Abbruch von Transaktionen verwendet werden. Im Gegensatz den Undo-Datensätzen können diese Listen zum einen beliebig lang werden und weisen zum andern zwischendurch immer wieder eingestreute Vollversionen des Datensatzes auf, um die Rekonstruktion nicht immer ganz von vorne beginnen zu müssen (siehe [6][7] für weitere Details).

Abb. 19 illustriert die Speicherung von zeitversionierten Daten in AIM-P. Der erste aktuelle Datensatz hat noch keine Updates erfahren, deshalb gibt es für ihn noch keinen Eintrag im Index des History-Pools. Der zweite aktuelle Datensatz wurde mit drei Update-Transaktionen verändert und hat deshalb 3 Delta-Einträge im History-Pool. Der dritte aktuelle Datensatz zeigt den Umgang mit langen Delta-Ketten. Hier kommt anstelle des ersten Delta-Eintrag ein spezielle Delta-Index, der anzeigt, der direkt auf zwischendurch angelegten Vollversionen verweist. Alle diese Einträge sind mit den Zeitstempeln der jeweiligen Update-Transaktion versehen, so dass man ggf. erst bei der passenden Vollversion mit der Rekonstruktion des historischen Datensatzes beginnt.
Auf HDBL-Ebene wurde der Zugriff auf eine historische Version der Datensätze durch den Zusatz „ASOF <datumsangabe>“ im der FROM-Klausel realisiert. Diese Zeitangabe wurde vom Query Processor via Complex Object Manager an den Subtuple Manager durchgereicht, der den gewünschten Datensatz zum gewüschten Zeitpunkt (falls vorhanden) wie einen ganz normalen Datensatz im Systempuffer bereitstellte. ... Beispiel ...
Benutzerdefinierte Datentypen und Funktionen
Die 1986 von Michael Stonebraker[62] publizierte Idee, die relationalen DBMS mit benutzerdefinierten Typen und Funktionen zu erweitern, inspirierte auch das AIM-P-Entwicklungsteam.
Workstation – DB-Server – Kooperation
Bereits Anfang der 1980er Jahre war absehbar, dass die bis dahin rein zentralrechner-basierten CAD-Anwendungen im Laufe der Jahre mehr auf sog. „CAD-Workstations“ verlagert werden.[37] Das zentrale Datenbanksystem wird mehr und mehr primär vor allem zur Zwischen- und endgültigen Speicherung der auf den CAD-Workstations erstellten Modelle benutzt.
NF2/eNF2 und der SQL:1999-Standard
Wie Internet-Recherchen mit Stichworten wie "NF2-Relationen", "geschachtelte Relationen", "nested relations" etc. zeigen, war diese Thematik ab Ende der 1980er / Anfang der 1990er Jahre sowohl im wissenschaftlichen Bereich als auch im kommerziellen Bereich weit verbreitet und so befasste sich natürlich auch das ISO-ANSI-Standardisierungsgremium - dem u.a. auch ein Mitarbeiter des AIM-P-Teams angehörte [63] - bei der Diskussion des nächsten SQL-Standards (damals als SQL3 bezeichnet ) mit diesem Thema. Jim Melton, der Editor des SQL:1999-Standards, schrieb später hierzu: "Even before the publication of SQL-92, work had begun on the next generation of the SQL-Standard, which was naturally called SQL3 in its project stage. SQL3 was planned to be a major enhancement of the language, adding object technology along with a host of more traditional relational database features (such as triggers). The object additions proved to be vastly more difficult - both technically and politically - than anybody hat anticipated. As a result, The "tradition" of publishing a revision of the SQL standard at three-year intervals fell apart and it took a full seven years to finish this version of the standard." [64], Seite 527
Leider scheint es keine allgemein verfügbaren Dokumente zu geben, die im Detail beschreiben, welche Alternativen seinerzeit im Standardisierungsgremium diskutiert und aus welchen Gründen sie letztlich akzeptiert oder verworfen wurden. Einen gewissen Einblick vermittelt lediglich die Aussage von Jim Melton: "Of the remaining commercial SQL products, both Oracle and IBM have delivered implementations of various portions of SQL:1999's object capabilities. ... It appears to me that Oracle's support has emphasized the use of structured user-defined types as rows of typed tables, while IBM's tends more toward the use of those UDT's as the rows of types of columns in ordinary tables. ... Sybase ... focusses on using Java as the underpinnings of its object-relational strategy." [64], Seite 18
Wenn man es vom letztlich verabschiedeten Standard SQL:1999 [65][64] her betrachtet, dann bestand offensichtlich Einigkeit darüber, dass man für anspruchsvollere Anwendungen ein Datenmodell benötigt, das Strukturen wie eNF2, d.h. atomare Werte, Tupel, (Multi-)Mengen, Listen und beliebige Kombinationen von diesen unterstützt. Unterschiedliche Auffassungen gab es jedoch offenbar darüber, wie dies SQL-seitig bzw. im Datenbanksystem realisiert werden sollte:
- ein Datenbanksystem mit einem nativen eNF2-Datenmodell à la AIM-P
- ein Datenbanksystem mit einem 1NF-Datenmodell, das abstrakte Datentypen unterstützt und auf diese Weise ein komplex-strukturierte Objekte unterstützt
oder eine Mischform aus beiden.
Die erste Variante würde eine massive Überarbeitung bzw. die Neuimplementierung vieler Komponenten der existierenden relationalen DBMS erfordern, wie z.B. die internen Speicherstrukturen, Indexe, Anfragebearbeitung, Anfrageoptimierung, Concurrency Control u.v.a.m. sowie die fundierte Klärung vieler damit in Zusammenhang stehender Fragen, wie z.B. Sortierung und Duplikatelimierung.[50]
Die zweite Variante hingegen würde nur relativ geringe Eingriff in den Systemkern erfordern, da die als "abstrakter Datentyp" realisierten Attribute für den Systemkern eine Art von "black box" sind, die mittels einiger weniger Systemfunktionen und ansonsten mittels benutzerdefinierter Funktionen und Prozeduren in die Anfragebearbeitung die normale 1NF-Anfragebearbeitung einbezogen werden. Natürlich verursacht auch diese Integration einen nicht unerheblichen Implementierungsaufwand für den DBMS-Hersteller, dieser ist aber bei weitem nicht so hoch wie bei der ersten Variante.
Nachdem in beiden Fällen letztlich eNF2-ähnliche Strukturen unterstützt werden können, spricht auf den ersten Blick eigentlich alles dafür, die zweite Variante zu wählen. ...
Betrachten wir hier zu ... Fortsetzung folgt ...
Puristen Relationale Algebra [66]
SQL-Kritik [67]
ANSI-ISO-Dokumente [68]
SQL3 / SQL:1999 [69]
Interview mit Jim Melton [70]
OO in DB2 [65]