Melden Sie sich hier an, um auf Kommentare und die Whitepaper-Datenbank zugreifen zu können.

Kein Log-In? Dann jetzt kostenlos registrieren.

Falls Sie Ihr Passwort vergessen haben, können Sie es hier per E-Mail anfordern.

Der Zugang zur Reseller Only!-Community ist registrierten Fachhändlern, Systemhäusern und Dienstleistern vorbehalten.

Registrieren Sie sich hier, um Zugang zu diesem Bereich zu beantragen. Die Freigabe Ihres Zugangs erfolgt nach Prüfung Ihrer Anmeldung durch die Redaktion.

07.03.1986 - 

Relationales Image allein reicht nicht aus:

IMS-Interface ist nach wie vor Zukunftsmusik

Die Unterstützung des relationalen Modells wird heute allgemein als Conditio sine qua non für moderne Datenbanksysteme angesehen. In dieser Liste glänzt IMS durch Abwesenheit. Interface-Probleme zeigt DB2-Entwickler Chris Date* auf.

Ein relationales Interface zu IMS erscheint sehr attraktiv. Es würde unter anderem bedeuten, daß eine an IMS gebundene Installation zumindestens einige der Vorteile des relationalen Ansatzes ernten kann, ohne daß irgendwelche existierenden Daten umgelagert und bestehende Programme umgeschrieben werden müssen. Leider gibt es jedoch gute Anhaltspunkte dafür, daß ein echtes relationales Interface zu IMS nie mehr als ein Wunschtraum sein wird.

Eine gegenteilige Frage liegt natürlich auf der Hand: Das Problem, ob es möglich sein kann, ein DL/1-Interface zu einem relationalen System wie DB2 anzubieten. Ein derartiges Interface stände als noch attraktivere Möglichkeit zur Diskussion. Es scheint mir in diesem Zusammenhang angebracht, eine Reihe vereinfachender Annahmen zu treffen, um die Diskussion übersichtlicher zu gestalten: Meine erste Annahme geht davon aus, daß das relationale Interface zur Unterstützung von IMS die strukturierte Abfrage-Sprache SQL (Structured Query Language) ist, die durch DB2 implementiert wird. Die meisten Punkte, die im folgenden angesprochen werden, treffen mit geringer Veränderung auf jedes relationale Interface zu, nicht nur auf SQL. Weiterhin gelten sie auch für jedes non-relationale System, nicht nur für IMS.

Zweitens nehme ich an, daß IMS Unterstützung für SQL im besonderen bedeutet, daß SQL-Operationen durch Übersetzung in Standard-DL/1 Aufrufe implementiert werden. Die alternative Möglichkeit, DL/1 ganz zu umgehen und die SQL-Statements direkt in I/O-Operationen zu übersetzen, ist mit Vorsicht zu genießen.

Last but not least habe ich die Wahl getroffen, IMS-Main-Storage-Datenbanken nicht zu betrachten. Hauptspeicher-Datenbanken sind wirklich ein Spezialfall in IMS; ihr Verhalten unterscheidet sich signifikant von den anderen Datenbanktypen, so unterstützen sie zum Beispiel verschiedene Datentypen.

Zwischen IMS und SQL bestehen einige grundlegende Inkompatibilitäten. Die Hauptquelle dieser Unverträglichkeit ist der verhältnismäßige Mangel an Disziplin, den IMS auferlegt. Der Benutzer erhält hier mehr Freiheit als es mit den allgemeinen Datenbankkriterien der Kontrolle, Stabilität und Datenunabhängigkeit vereinbar ist. Die Folge: Bei IMS treten viele Situationen auf, in denen die Bedeutung der Daten zumindest teilweise in prozeduralem Code verborgen ist, statt in einigen IMS-Datendefinitionen verdeutlicht zu werden. Oft ist es unmöglich, eine solche versteckte Bedeutung durch ein geregeltes relationales Interface aufzudecken, das alle Informationen in der Datenbank benötigt, um durch deutliche Feldwerte repräsentiert zu sein.

Zwischen IMS und DB2 gibt es wichtige Unterschiede

Die grundlegende Datenmenge ist in den beiden Systemen unterschiedlich - in IMS ist es das Segment, in SQL der Record. Ein IMS-Segment ist lediglich ein Byte-String; ein SQL-Record ist im Gegensatz dazu eine Sammlung von namentlich gekennzeichneten, geschriebenen Werten. Daher sind verschiedene Feldbeschreibungen in IMS möglich, in SQL jedoch nicht:

- Anonyme oder undefinierte Felder:

Das Segment Typ S kann beispielsweise als 100 Bytes lang definiert sein. Davon sind die Bytes 1 bis 10 als Feld A, die Bytes 91 bis 100 als Feld Z definiert und die Bytes 11 bis 90 undefiniert. Realistischer ist, anonyme Felder als Mittel einzusetzen, um zuzulassen, daß viele verschiedene Segmenttypen die gleiche Position in der Hierarchie einnehmen. Das Segment Typ S (100 Bytes) läßt sich zum Betspiel mit nur einem benamten Feld "Segtype" (angenommen Bytes 1 bis 4) definieren; das Benutzerprogramm kann dieses Feld testen, dann das Segment intern auf einem Set angemessener Programmvariablen abbilden.

- Künstlich überlappende Felder:

Die Bytes 1 bis 10 eines Segmentes sollen zum Beispiel als Feld A die Bytes 6 bis 13 als Feld B definiert werden. Diese Möglichkeit kann auch in Verbindung mit der vorigen benutzt werden, um zuzulassen, daß verschiedene Segmenttypen an der gleichen hierarchischen Position erscheinen; sie ist aber nicht an solch einen Zusammenhang gebunden. Ein vernünftigeres Anwendungsbeispiel besteht darin, zusammengesetzte Felder zu unterteilen - zum Beispiel können die Bytes 12 bis 17 als Datum-Feld definiert werden und dabei die Bytes 12 bis 13, 14 bis 15 und 16 bis 17 wieder jeweils als "Jahr"-, "Monat"- und "Tag"-Feld. Es ist sicherlich richtig, daß die Unterstützung von zusammengesetzten Feldern in relationalen Sprachen wie SQL stark gebraucht wird, künstlich überlappende Byte-String-Felder zuzulassen ist aber für dieses Problem nicht die beste Lösung.

- Verschiedene Datentypen für dasselbe "Feld":

Bytes 1 bis 10 eines Segmentes können zum Beispiel als Typ P (packed dezimal) und Bytes 6 bis 13 als Typ X (hexadezimal) definiert werden. Diese Möglichkeit kann wieder in Verbindung mit der Technik anonymer oder undefinierter Felder eingesetzt werden. Damit wird zugelassen, daß multiple Segmenttypen die gleiche Position teilen, aber eine Beschränkung auf diesen Zusammenhang besteht nicht.

Bei IMS gibt es folgende Datentypen:

- C (character): entspricht dem SQL,

- Datentyp CHAR,

- X (hexadezimal): kein SQL-Äquivalent,

- P (packed dezimal): kein SQL-Äquivalent.

Es ist besonders zu beachten, daß der IMS-Typ P nicht dem SQL Typ Dezimal entspricht. IMS Typ P und SQL Dezimal unterscheiden sich zumindestens in den beiden folgenden Punkten:

- Die Datentypen werden gewöhnlich in IMS nicht überprüft. Daher gibt es keine Garantie, daß ein Feld vom Typ P tatsächlich eine valide kompakte Dezimalzahl enthält. Ist das nicht der Fall, können Benutzerprogramme beim Ausführungslauf versagen.

- Alle Vergleiche in IMS werden üblicherweise Bit für Bit von links nach rechts ohne Berücksichtigung des Datentyps durchgeführt. Daher wird zum Beispiel in IMS die gepackte Dezimalzahl "-1" wahrscheinlich als größer angesehen als die gepackte Dezimalzahl "+ 1"; ebenso müssen zwei Werte, die unter den Regeln des System/370 zur Repräsentation von gepackten Dezimalzahlen gleich sind, nicht tatsächlich als gleich angesehen werden, wenn sie verschiedene Zeichencodes haben. Daraus folgt, daß ein neuer SQL-Datentyp entsprechend dem IMS-Typ P mit eigenen bizarren Vergleichsregeln erfunden werden muß, wenn ein IMS-Segment als SQL-Record ausgegeben werden soll. Für Typ X treffen natürlich analoge Anmerkungen zu. Außerdem kann SQL-Dezimal Noninteger-Werte repräsentieren, obwohl diese Tatsache für die gegenwärtige Diskussion nicht von Bedeutung ist.

User muß Feldwerte genau spezifizieren

Es mag den Anschein haben, daß die IMS-Typen C, P und X tatsächlich alle gleich wären - alle sind Byte-Strings und lassen sich wie der SQL-Typ CHAR abbilden. Das trifft dennoch nicht zu, denn es bestehen feine Unterschiede. Als ein Beispiel hierfür kann die Diskussion der Segmente variabler Länge im nächsten Abschnitt angesehen werden.

Drei IMS-Segmente können variable Länge haben. Natürlich können das SQL-Records auch, aber mit einer Reihe entscheidender Unterschiede: - Grundlegend hat ein SQL-Record eine variable Länge, wenn er ein oder mehrere Felder variabler Länge enthält - zum Beispiel Felder, die für das System ausdrücklich als Felder variabler Länge definiert wurden.

- Im Gegensatz dazu gibt es in IMS keine Erwähnung von Feldern variabler Länge. Statt dessen wird ein Segment variabler Länge als Byte-String einer festgelegten Maximallänge definiert, der aus einem Set von Feldern bestimmter (festgelegter) Länge besteht. Ist dieses Segment in einem bestimmten Fall kleiner als die Maximallänge, wird einfach angenommen, daß die Felder am rechten Ende fehlen, entweder ganz oder teilweise.

Angenommen, ein Segment Typ S (Maximallänge 1000 Bytes) ist zum Beispiel als zusammengesetzt aus den Feldern A, B, C und D definiert und sowohl A, B, C und D sind 25 Bytes lang. Wird weiter angenommen, daß ein bestimmter Fall von S nur 65 Bytes lang ist, dann wird davon ausgegangen, daß in diesem Fall die letzten 10 Bytes von Feld C und das gesamte Feld D fehlen.

Wenn der Anwender "sensitiv" für ein fehlendes oder teilweise fehlendes Feld ist, werden beim Wiederauffinden fehlende oder teilweise fehlende Felder im I/O-Bereich des Anwenders mit Leerzeichen (bei Typ C) oder Binärnullen (bei Typ X) angefüllt. Es ist zu beachten, daß "Fehlen" in IMS nicht das gleiche bedeutet wie "Null" in SQL. Die Suche nach einem fehlenden Feld wird immer mit dem Ergebnis "nicht gefunden" enden, ohne Rücksicht auf die spezifizierten Suchbedingungen.

Natürlich beinhaltet jedes Vorkommen eines Segmentes variabler Länge ein Längenfeld, daß die tatsächliche Länge dieses bestimmten Falls spezifiziert. Weiterhin wird das Längenfeld dem Benutzer angezeigt. Der Benutzer zeichnet im besonderen verantwortlich dafür, einen Wert für das Feld zu spezifizieren, wenn ein Vorkommen des Segments gespeichert wird. Für das Auffinden kann das Längenfeld als Grundlage benutzt werden, um zwischen verschiedenen Segmenttypen zu unterscheiden, denen die gleiche Position in der Hierarchie zugewiesen worden war. Beispiel: "Wenn Länge = 52, dann ist dies ein Segment Typ X, wenn Länge = 86, dann ist dies ein Segment Typ Y." Dieser Trick kann ein separates "Segtype"-Feld überflüssig machen.

Die Sammlung aller Segmente eines gegebenen Typs ist in IMS reguliert, während die Sammlung aller Records eines gegebenen Typs in SQL nicht geordnet ist. Ein gegebenes Set von Records wird in SQL nur dann garantiert in einer bestimmten Reihenfolge zurückgegeben, wenn die Suchfrage eine angemessene "Order by"-Anweisung enthält. Diese Tatsache legt nahe, daß in dem Fall, wenn IMS-Segmente über ein relationales Interface als SQL-Records erscheinen, SQL-"Selects" für diese Records eine "Order by"-Anweisung enthalten müssen, die die Reihenfolge spezifiziert, die IMS tatsächlich anwendet. Sonst werden SQL-Programme, die mit IMS-Daten arbeiten, sehr wahrscheinlich einige unerfreuliche Datenabhängigkeiten enthalten.

Begriff der "logischen DB" kann irreführend sein

Tatsächlich sind nicht alle IMS-Reihenfolgen in SQL auszudrücken. Es ist vielmehr so, daß die einzige Form der Reihenfolge in IMS, die ein exaktes SQL-Äquivalent hat, die Ordnung nach einem "eindeutigen Sequenz-Feld" bedeutet. Segmente in IMS, die nicht über ein eindeutiges Sequenz-Feld verfügen, werden in einer der folgenden Arten geordnet:

- Haben die Segmente überhaupt kein Sequenz-Feld, dann sind die Möglichkeiten "first", "last" und "here" gegeben.

- Haben die Segmente ein Sequenz-Feld, aber ist dies nicht eindeutig, dann dient das Sequenz-Feld als Haupt-Item für die Reihenfolge; aber die Sets von Duplikaten werden innerhalb der Hauptsequenz wieder nach "first", "last" oder "here" geordnet.

"First" bedeutet, daß ein neues Segment vor den bereits bestehenden Segmenten gespeichert wird. "Last" heißt daß ein neues Segment nach den bereits existierenden Segmenten gespeichert wird. "Here" sagt aus, daß die Reihenfolge durch das Anwenderprogramm kontrolliert wird - die Speicherung eines neuen Segments erfolgt an einer Position, die prozedural durch den Programmcode des Benutzers spezifiziert ist.

"First", "last" und "here" sind Beispiele der sogenannten "unentbehrlichen Ordnung". Eine Ordnung ist unentbehrlich, wenn Information verlorengeht, im Falle, daß diese Ordnung zerstört wird. Es ist zu beachten, daß nach dieser Definition die Ordnung nach einem eindeutigen Sequenz-Feld nicht unentbehrlich ist, da es immer noch möglich ist, zum Beispiel den Angestellten mit der vierthöchsten Seriennummer zu finden, auch wenn die Angestellten ursprünglich nicht in der Datenbank nach Seriennummern geordnet waren. Relationale Systeme - SQL im besonderen - unterstützen absichtlich keine Form unentbehrlicher Ordnung.

- Eine letzte, vergleichsweise kleinere Inkompatibilität: (Nur) im Fall von Hauptspeicher-Datenbanken haben die IMS-Update-Operationen unkonventionelle Semantik. Wenn eine Transaktion T ein Segment S auf den neuesten Stand bringt und dann dies Segment S wieder aufruft, wird keine Auswirkung des eigenen Update zu sehen sein. Der Grund liegt darin, daß IMS das Update nicht tatsächlich auf die Datenbank anwendet, bis das Ende der Transaktion erfolgreich erreicht ist, und diese Tatsache wird dem Benutzer unglücklicherweise vor Augen geführt.

Dennoch ist es bei einer gegebenen Sammlung von IMS-Daten möglich, eine Vielzahl von "oberflächlichen Abbildungen der Records" (flat record views) dieser Daten zu konstruieren. Natürlich ist so eine oberflächliche Record-Abbildung nicht dasselbe wie eine SQL-Beziehung. Die Definition einer solchen oberflächlichen Abbildung beinhaltet eine Reihe von IMS-Operationen, die verschiedene vordefinierte hierarchische Pfade durchwandern (siehe Abbildung 1).

Ein Beispiel: Gegeben ist eine IMS-Repräsentation der bekannten Lieferanten- und -Teile-Datenbank. In IMS beinhaltet sie tatsächlich zwei physische Datenbanken:

Segment Typ S (Lieferant) hat zwei Felder: S # (Lieferanten-Nummer): eindeutiges Sequenz-Feld und SCITY (Lieferanten-Stadt). Ebenso hat das Segment Typ P (Teil) zwei P# (Teil-Nummer): eindeutiges Sequenz-Feld und PCm (Teil-Stadt). Auch das Segment Typ SP (Versand) verfügt über zwei Felder, nämlich P# (Teil-Nummer) als eindeutiges Sequenz-Feld und QTY (Anzahl).

Zu jeder gegebenen Zeit kann höchstens eine Auslieferungsmöglichkeit für eine gegebene Kombination Lieferant/Teil existieren, daher ist das Feld SP P# "eindeutig innerhalb der Parent-Beziehung (unique within parent), wobei "Parent" "Lieferant" bedeutet. Tatsächlich ist das Segment Typ S der physikalische Ursprung des Segments Typ SP, und das Segment Typ P ist der logische Ursprung. Ebenso ist SP ein physikalischer Abkömmling von S und ein logischer Abkömmling von P. Der Zeiger von dem Segment-Typ SP zu dem Segment P ist ein logischer Ursprungszeiger. Im allgemeinen wird IMS das Feld SP.P # als virtuell zulassen, aber hier soll es als Sequenz-Feld für den Segment-Typ SP benutzt werden; das heißt, daß es physikalisch, nicht virtuell sein muß. Die SP-Segmente für ein gegebenes S-Segment sind also in P # -Reihenfolge angeordnet.

Es ist übrigens zu beachten, daß diese beiden IMS-Datenbanken "passendes Verhalten" zeigen. Mit diesen beiden gegebenen physikalischen Datenbanken ist es möglich, eine logische Datenbank zu definieren (siehe Abbildung 2):

Es ist zu beobachten, daß die Definition dieser oberflächlichen Record-Abbildung eine Menge Vordefinition der physikalischen Zugangspfade auf der Diskette und beachtliche professionelle IMS Kenntnisse bei der Konstruktion der Abbildung erfordert. "Relationale" Benutzer werden sicher nicht in der Lage sein neue oberflächliche Abbildungen der Records für sich selbst zu definieren, wenn die Notwendigkeit erscheint.

Tatsächlich wurde ein Definitionsschritt ausgelassen - der Schritt zur Definition eines Programm-Kommunikations-Blocks (PCB) für die logische Hierarchie. Aus Vereinfachungsgründen sei davon ausgegangen, daß PCB eine Hierarchie definiert, die mit der als logische Datenbank definierten identisch ist.

Es muß in diesem Zusammenhang hervorgehoben werden, daß der Begriff "logische Datenbank" etwas irreführend ist, da "logische" Datenbanken eigentlich in IMS eher physische sind. Mit Sicherheit beinhaten sie alle Arten physischer Zugangspfade auf der Diskette, genau wie es die physischen Datenbanken tun.

Wie bereits angedeutet, sollte ein IMS-Experte für das Schreiben von oberflächlichen Record-Abbildungen verantwortlich sein - besonders für das Schreiben eines einfachen Sets von DL/ 1-Aufrufen, die als Teil des Übersetzungsprozesses von SQL zu DL/ 1 aufgerufen werden.

Wie steht es nun mit der Möglichkeit, DL/1 zu übergehen und SQL-Operationen direkt in I/O-Operationen gegen die gespeicherten IMS-Daten zu übersetzen? Kann es möglich sein, eine Komponente - die ich SQL-Datenmanager nenne - mit der Aufgabe zur Verfügung zu stellen, SQL Zugang zu den gespeicherten TMS-Daten in genau der gleichen Art anbieten, in der der DL/1-Datenmanager heute DL/1 Zugang zu solchen Daten in IMS bietet? Ein solcher SQL-Datenmanager könnte zum Beispiel die SQL-Anweisung "Order by" durch die Ausführung einer dynamischen Sortierung unterstützen, anstatt nur auf die Reihenfolgen beschränkt zu sein, die statistisch vordefiniert sind.

Es ist allerdings immer noch mit Schwierigkeiten zu rechnen - zum Beispiel bei Daten, die nicht mit ihren erklärten Datentypen übereinstimmen, anonymen und überlappenden Feldern sowie unentbehrlichen Reihenfolgen. Zumindest scheint es, daß für die gespeicherten Daten ein separates Set von SQL-Definitionen für die bereits bestehenden DL/ 1-Definitionen erforderlich ist; und weiter würde das Problem auftreten, zwei Definitionssets in Synchronisation zu halten.

Es mag möglich sein, einige Schwierigkeiten durch Exit-Routinen zu lösen, deren Funktion darin besteht, die IMS-Daten zu "säubern", bevor sie SQL angeboten werden. Um in der Lage zu sein, solche Routinen zu schreiben, wäre es jedoch zunächst einmal notwendig, die Bedeutung der IMS-Daten zu verstehen - und (wie bereits vorher erklärt) ein Teil dieser Bedeutung wird sich im allgemeinen in prozeduralem User-Code befinden. Daher muß der Mitarbeiter, der Exit-Routinen schreibt, wahrscheinlich viele Anwenderprogramme untersuchen, um diese Bedeutung aufzudecken. Kann es da jemals eine Garantie geben, daß ein solcher Prozeß zum Abschluß kommt?

Als wichtig erscheint mir auch die Frage, was ein solcher SQL-Datenmanager beinhalten würde. Hierbei handelt es sich um eine zumindest genauso schwierige Aufgabe wie die, einen DL/ 1-Datenmanager für IMS zu konstruieren.

SQL ist nämlich, funktional gesprochen, eine viel reichere Sprache. Außerdem wäre aus demselben Grund wie bei DB2 ein Optimierer nötig, denn ohne ihn wäre die Performance nicht tolerabel.

Fast alle bestehenden Arbeiten zu relationaler Optimierung gehen davon aus, daß die Zielspeicherstruktur auf Indizierung, "Hashing" oder einer Kombination aus beidem besteht. Zur Optimierung IMS-artiger Strukturen auf Zeigerbasis wurde nach meiner Kenntnis noch kaum etwas veröffentlicht. Ein SQL-Datenmanager, der direkt mit IMS-Speicherdaten arbeitet, ist sicherlich kein triviales Unterfangen und erfordert wahrscheinlich ein bestimmtes Maß an Anpassung (hand-tayloring) durch den DBA. Ein solcher Versuch gehört auch immer noch mehr in den Bereich der Forschung als in den kommerzieller Produkte und ist vom technischen Aspekt aus mit großen Schwierigkeiten behaftet. Selbst wenn sich diese Probleme lösen lassen, sagt dies noch nichts über die Frage der Kosteneffektivität aus.

Zwar mag es zutreffen, daß IMS, als Ziel für ein relationales Interface komplexer als ein non-relationales System ist. Dennoch sollte klar werden, daß sehr wahrscheinlich Probleme auch mit anderen Systemen auftreten. Wird die Investition in ein nicht-relationales System erwogen, das den Anspruch erhebt, ein relationales Interface zu unterstützen, dann ist es ratsam, es sicher zu wissen, was das Interface wirklich beinhaltet, bevor Verpflichtungen eingegangen werden.

Schließlich noch eine Anmerkung zu der entgegengesetzten Frage, ob es möglich ist, ein DL/ 1-Interface zu einem relationalen System wie DB2 zu unterstützen. Die Antwort lautet kurz und bündig: nein. Erstens bestehen einige grundlegende Inkompatibilitäten. So scheint es zum Beispiel nicht möglich zu sein, das Verhalten der Reihenfolgen in der Art von "here" oder die IMS-artigen Segmente variabler Länge an der Spitze von SQL-Records zu simulieren.

Ferner würde die Unterstützung von DL/1 -Update-Operationen unter anderem SQL-Unterstützung für Fremdschlüssel erfordern.

Schließlich stellen sogar die Retrieval-Operationen ein Problem dar. Zum Beispiel sind DL/1-Operationen entscheidend von verschiedenen Anmerkungen zur "derzeitigen Position", (derzeitiges Segment, derzeitiger Ursprung U.S.W.) abhängig. Die Anmerkung zu "derzeitigem Parent" kann zusammenbrechen, weil SQL keine Fremdschlüssel-Begrenzungen aufzwingt; ein gegebenes "Child" mag tatsächlich noch nicht einmal irgendeinen "Parent" in der SQL-Datenbank haben.

Zusätzlich zu all diesen Faktoren besteht natürlich das Problem, daß die Implementation von DL/1 in einem relationalen System - wenn überhaupt möglich - mit hoher Wahrscheinlichkeit eine sehr schlechte Leistung zeigen wurde; denn die Simulation einer Sprache auf Record-Level wäre mit Sicherheit an der Spitze eines Set-Level-Interface angesiedelt.

Echte relationale Systeme bieten absichtlich kein Interface zu den Daten auf niedrigerem Level, um die Möglichkeit auszuschließen, daß Anwender die relationalen Kontrollen übergehen und dadurch das System auf verschiedene Arten untergraben. Tatsächlich kann dieser letzte Punkt als noch eine weitere Unterscheidung zwischen echten relationalen Systemen auf der einen und nur anscheinend relationalen Systemen auf der anderen Seite gesehen werden. In diesem Fall besteht immer die Möglichkeit, daß ein Anwender eine Operation durchführt, die das System unterminiert. Ein wirklich relationales System läßt solche "subversiven" Aktivitäten nicht zu.

* Chris Date ist Vizepräsident des Relational Institute, San Jose.