Überlegungen zur Ergänzung des Datenbanksystems DB2:

Integritätsregeln können DB-Update gefährden

09.12.1988

Zwar bedeuten die in dem DB2-Release 2.1 realisierten Integritätsregeln eine gewisse Arbeitserleichterung, konstatiert Hermann Schmitt. Doch der Praktiker hat noch eine Reihe von Problemen ausgemacht, zu denen er einige Lösungsansätze präsentiert. Insbesondere bezüglich der "Delete"-Anweisung entdeckt Schmitt "nicht unbedingt eine Verbesserung der Sicherheit".

Das wichtigste Charakteristikum einer Datenbank ist, daß Segmente (Zeilen) verschiedenen Typs in der Datenbank vorhanden sein und durch Einrichtungen des Datenbanksystems miteinander in Beziehung gesetzt werden können. Die Bezeichnungen Hierarchische Datenbank oder Netzwerkdatenbank, die in der Literatur häufig gebraucht werden, dürfen nicht zu der Vorstellung verleiten, daß solche Strukturen nur in diesen Datenbanksystemen realisiert werden können. Auch die Relationalen Datenbanksysteme sind geeignet, diese Strukturen abzubilden.

Unterscheidungsmerkmal für Datenbanken ist vor allem, wie die Beziehungen zwischen den Segmenten realisiert werden. Insbesondere ist das Relationale Datenbankmodell dadurch charakterisiert, daß Beziehungen ausschließlich über Inhalte von Feldern hergestellt werden, die in den Zeilen (Segmenten) selbst enthalten sind.

Alle Schlüssel sollten in der Datenbank stehen

Felder, über die standardmäßig Beziehungen zwischen Zeilen hergestellt werden, sind die Schlüsselfelder. Hierbei können die Zeilen unterschiedlichen, aber auch der gleichen Tabelle angehören. Alle Schlüsselfelder zusammen, über die eine bestimmte Beziehung hergestellt wird sind Schlüssel. Unter dem Gesichtspunkt der Über-/

Unterordnung sind die Schlüsselfelder angeordnet. Neben den Beziehungen zwischen Zeilen wird auch der Primärzugriff von außen auf Zeilen normalerweise über Schlüssel bewerkstelligt. Besteht Gleichheit zwischen Schlüsselfeldern, so "stehen die Zeilen in Beziehung" (allgemeiner könnte man auch weitere Vergleichs-Operatoren betrachten wie "größer/gleich" oder "kleiner/gleich" etc.).

Die Schlüssel erhalten Namen, die nur innerhalb einer Tabelle eindeutig sein müssen. Bei Schlüsseln, die nur aus einem Feld bestehen, ist der Schlüsselname gleich dem Feldnamen zu setzen, andernfalls darf der Schlüsselname nicht mit einem Feldnamen identisch sein. Man unterscheidet dabei zwischen eindeutigen und nichteindeutigen Schlüsseln. Ein Schlüssel wird als eindeutig "UNI" bezeichnet, wenn alle Schlüssel nur

einmal in der Tabelle vorhanden sind, soweit sie kein leeres Feld enthalten.

Ein Feld wird als "leer" bezeichnet, wenn es NULL ist, weiter wird es auch dann als leer bezeichnet, wenn es als "NOT NULL WITH DEFAULT" definiert ist und 0 beziehungsweise Blank enthält. Ein Schlüssel wird dann als "leer" bezeichnet, wenn er ein Feld enthält, das leer ist. Gilt für einen Schlüssel einer Tabelle, daß er für keine Zeile "leer" ist, so hat der Schlüssel die Eigenschaft "nicht leer" (NL).

Jede Tabelle sollte mindestens einen Schlüssel enthalten, der eindeutig und für keine Zeile leer ist. Dadurch soll ermöglicht werden, jede Zeile eindeutig zu spezifizieren und direkt auf jede Zeile zuzugreifen. Einer der Schlüssel mit diesen Eigenschaften ist als Primärschlüssel auszuwählen.

These 1:

- Alle Schlüssel sollten in der Datenbank verzeichnet sein. Hierbei sind der Name des Schlüssels zu spezifizieren und die Felder, aus denen der Schlüssel besteht. Weiter sind die Eigenschaften des Schlüssels anzugeben: Primärschlüssel, eindeutig, NOT NULL.

Erläuterungen zu These 1: Hierdurch werden die Schlüssel und ihre Eigenschaften spezifiziert. Die Einhaltung der Eigenschaften kann durch ein Service-Programm überwacht werden. Insbesondere sind die Primärschlüssel festzulegen. Schon beim Datenbank-Design kann dadurch nachgeprüft werden, ob für jede Tabelle ein Primärschlüssel vorhanden ist.

Auf den Schlüsseln bauen die Beziehungen auf. Wie schon im vorigen Abschnitt erläutert, wird eine Beziehung hergestellt durch zwei korrespondierende Schlüssel, die auf Gleichheit geprüft werden. Eine Beziehung heißt gerichtet, wenn sie von einer Tabelle x zu einer Tabelle y führt. Zu jeder Beziehung gehört eine Co-Beziehung, die durch die gleichen Verbindungen, aber in umgekehrter Richtung, gebildet wird.

Aus der Definition einer Beziehung ergibt sich, daß bei DB2 korrespondierende Schlüssel gleich viele Felder haben müssen und korrespondierende Schlüsselfelder entweder beide Zeichenketten oder beide numerisch sein müssen. Aus Effizienzgründen ist eine genaue Entsprechung des Feldtyps erstrebenswert. Bei der Definition von Beziehungen, für die vom DB2-System die referentielle Integrität geprüft werden soll, wird eine genaue Entsprechung der Felddefinition verlangt.

Da von einer Zeile mehrere Beziehungen ausgehen können - ja sogar mehrere Beziehungen zur gleichen Zielzeile - erhalten die Beziehungen zweckmäßigerweise Namen. Sie müssen nur innerhalb der Ausgangszeile eindeutig sein. Eine Beziehung von einem beliebigen Schlüssel zu einem eindeutigen Schlüssel heißt eine "zu 1"-Beziehung (:1). Eine Beziehung von einem beliebigen Schlüssel zu einem nichteindeutigen Schlüssel heißt eine "zu n"-Beziehung (:n).

Ein wichtiger Sonderfall besteht darin, daß eine Ausgangszeile zu mehreren Zielzeilen mit unterschiedlichen Schlüsselwerten in Beziehung gesetzt werden soll. Diese Beziehung wird dadurch realisiert, daß eine zusätzliche Tabelle (Verbindungstabelle) eingeführt wird, die pro Kombination aus Ausgangsschlüssel und einem Zielschlüssel eine Zeile enthält.

Die Beziehung zwischen Schlüsseln muß klar sein

Die dann mittelbare Beziehung wird hergestellt mit Hilfe des Ausgangsschlüssels zwischen Ausgangstabelle und Verbindungstabelle und mittels des Zielschlüssels zwischen Verbindungstabelle und Zieltabelle. Wie schon erwähnt, sind beide genannten Schlüssel in der Verbindungstabelle enthalten. Eine Speicherung aller Zielschlüssel in der Ausgangstabelle würde dem Prinzip der Normalformen widersprechen.

Mit Hilfe der Verbindungstabelle wird diese Art der Beziehung auf die allgemeine Form von Beziehungen zurückgeführt. Die Kombination aus Ausgangsschlüssel und Zielschlüssel kann der Primärschlüssel der neuen Tabellen sein, falls die beiden Schlüssel eindeutig sind. Es kann aber auch zweckmäßig sein, eine laufende Nummer zusätzlich als Primärschlüssel einzuführen.

Ein wichtiges Charakteristikum einer Beziehung ist die Eigenschaft REQUIRED. Dies besagt, daß zu jeder Ausgangszeile (Ausgangsschlüssel) mindestens eine Zielzeile (Zielschlüssel) gehören muß. Ein wichtiger Sonderfall einer solchen Beziehung besteht dann, wenn der Zielschlüssel der Primärschlüssel einer Tabelle ist. In diesem Fall nennt man den Ausgangsschlüssel Fremdschlüssel (Foreign Key). Für diese Konstellation können in Version 2 von DB2 Integritätsregeln festgelegt werden, die das DB2-System gewährleistet. Der Begriff Fremdschlüssel wird im folgenden auch allgemeiner für Schlüssel verwandt, wenn sie zum Verweis auf Zeilen anderer Tabellen oder der gleichen Tabelle benutzt werden.

These 2:

- Alle Beziehungen sollten in der Datenbank verzeichnet sein. Hierbei sind der Name der Beziehung zu spezifizieren, erläuternder Text zu der Beziehung, der Ausgangsschlüssel, der Zielschlüssel und die Eigenschaften der Beziehung (insbesondere "REQUIRED").

Erläuterungen zu These 2: Schon beim Datenbank-Design sollte geklärt werden, welche Beziehungen zwischen den Tabellen notwendig sind. Eventuell ergibt sich dabei, daß zusätzliche Fremdschlüssel in die Tabellen eingefügt werden müssen. Weiter müssen die Eigenschaften korrespondierender Schlüsselfelder aufeinander abgestimmt werden.

These 3:

- Die dokumentierten Beziehungen sollten dazu genutzt werden, Selektionen zu vereinfachen, die Felder aus mehreren Tabellen holen.

Erläuterungen zu These 3: Die Selektion von Feldern aus mehreren Tabellen ist mit den heutigen Mitteln umständlich. Sie kann durch die dokumentierten Beziehungen wesentlich erleichtert werden. Dies ist auf zwei Arten möglich:

1. Es kann ein Dialogprogramm erstellt werden, das in folgender Weise funktioniert: Zunächst werden die Datenbanknamen mit beschreiben dem Text angezeigt. Bei Auswahl einer Datenbank werden die Tabellennamen der in der Datenbank enthaltenen Tabellen mit beschreibendem Text angezeigt. Bei Auswahl einer Tabelle werden deren Felder mit beschreibendem Text angezeigt.

Von dieser Anzeige können Felder selektiert werden, die ausgewertet werden sollen. Bei Verlassen der Anzeige werden die Beziehungen mit beschreibendem Text angezeigt, die von der Tabelle ausgehen. Wird eine Beziehung ausgewählt, so werden die Datenfelder der Tabelle angezeigt, zu der die Beziehung hinführt. Hierdurch schließt sich der Kreis. Mit Hilfe der dokumentierten Beziehungen kann die SELECT-Anweisung aufgebaut werden.

2. Man könnte auch an eine Erweiterung der SELECT-Anweisung selbst denken und zwar in folgender Weise:

SELECT T1.F11, T1.F12,..., T1.F1m1

T2.F21, T2.F22,..., T2.F2m2

...

Tn.Fn1, Tn.Fn2,..., Tn.Fnmn

FROM (T1,Bez1), (T2,Bez2),...

(Bez1, Bez2 sind Beziehungen, die von T1 beziehungsweise T2 ausgehen.)

Durch das Aneinanderreihen von Beziehungen in der Weise, daß die "Zieltabelle" der einen Beziehung Ausgangstabelle einer anderen Beziehung ist, können hierarchische und Netzwerkstrukturen gebildet werden. Die Schlüssel der beiden Beziehungen können dabei völlig unabhängig voneinander sein.

Hierarchische Strukturen behalten ihre Bedeutung

Es muß unterschieden werden zwischen den Beziehungen, die insgesamt vorhanden sind - sie bilden oft ein allgemeines Netzwerk - und den Beziehungen beziehungsweise Strukturen, die in einem einzelnen Programm verarbeitet werden. Unter dem zweiten Gesichtspunkt haben hierarchische Strukturen in der Datenverarbeitung eine große Bedeutung, weil sie auf der einen Seite vielfältig anwendbar, auf der anderen Seite aber auch in einem Programm relativ einfach verarbeitbar sind.

So sind auch im lMS durchaus Netzwerkstrukturen darstellbar, die allgemeiner sind als die hierarchischen Strukturen. In den Programmen können aber nur hierarchische Strukturen verarbeitet werden. Derartige Strukturen werden in der Datenverarbeitung sowohl durch Verknüpfung verschiedener Segmente (Zeilen) als auch innerhalb eines Segmentes durch geeignete Anordnung der Datenfelder im "Segment" in Verbindung mit geeigneten Datendefinitionen in der jeweiligen Programmiersprache realisiert.

Der Strukturbegriff ist der Begriff, mit dem die Normalisierung auf das folgende Grundprinzip zurückgeführt werden kann:

Ziel der Normalformen ist es, alle Strukturen aus den Zeilen zu beseitigen, oder anders ausgedrückt, die Zeilen sollen die einfachste Struktur erhalten, die möglich ist.

Auf die Theorie der Normalformen wird hier nicht näher eingegangen. Es sei aber darauf hingewiesen, daß die Anwendung der Theorie der Normalformen meist zu einer Zerlegung von Tabellen in mehrere Tabellen führt.

These 4:

- Alle hierarchischen Strukturen sollten in der Datenbank verzeichnet sein. Hierbei sind der Name der Struktur zu spezifizieren, beschreibender Text zu der Struktur, die "Root-Tabelle", und die Beziehungen, aus denen sich die Struktur zusammensetzt.

Erläuterungen zu These 4: Schon beim Datenbank-Design sollte geklärt werden, welche Strukturen für den Sachbereich von Bedeutung sein können.

Die Anwendung der Theorie der Normalformen führt dazu, daß sachlich zusammengehörige Daten auf mehrere Tabellen aufgeteilt werden. Der Begriff der Struktur erlaubt es, die Daten wieder als Einheit zu sehen. Eine Tabelle kann dabei mehreren Strukturen angehören.

These 5:

- Die dokumentierten Strukturen sollten dazu genutzt werden, Selektionen zu vereinfachen, die Felder aus mehreren Tabellen - aber einer Struktur - holen.

Erläuterungen zu These 5: Hier gilt Ähnliches wie bei These 3. Die Selektion kann auf zwei Arten erleichtert werden:

1. Mit Hilfe eines Dialogprogramms analog zu These 3 mit dem Unterschied, daß zunächst die Strukturen mit beschreibendem Text zur Auswahl einer Struktur angezeigt werden. Bei der Auswahl von Beziehungen werden nur Beziehungen angezeigt, die zu der betreffenden Struktur gehören.

2. Weiter wäre auch wieder eine Erweiterung der SELECT-Anweisung selbst denkbar in folgender Form:

SELECT T1.F11, T1.F12,..., T1.F1m1

T2.F21, T2.F22,..., T2.F2m2

Tn.Fn1, Tn.Fn2,..., Tn.Fnmn

FROM STRUCTURE SX (SX ist der Name einer Struktur)

Hierbei können auch noch die Qualifier der Feldnamen weggelassen werden, wenn die Feldnamen in der Struktur eindeutig sind. Dadurch wäre die Tabellenstruktur für den Anwender transparent.

These 6:

- Es sollte eine Selektionsform bereitgestellt werden, die alle Tabellenzeilen berücksichtigt, die mit den ausgewählten Rootzeilen in Verbindung stehen, auch wenn nicht alle Zeilentypen vorhanden sind. (Eine Art "Outer Join" im Gegensatz zum "Inner Join".)

Erläuterungen zu These 6: Beim derzeit realisierten "Inner Join" werden Feldkombinationen nur selektiert, wenn alle Felder vorhanden sind. Oft wäre es nützlich, auch Kombinationen zu selektieren, bei denen die Baumstruktur unvollständig ist aber von der Roottabelle her gesehen zusammenhängend. Eine Realisierung wäre wieder analog zu These 3 durch ein Dialogprogramm oder durch eine Erweiterung der SELECT-Anweisung möglich.

Beim Dialogprogramm könnte die Spezifikation der Auswertung durch den Benutzer völlig identisch sein mit der Spezifikation beim "Inner Join". Erst vor der automatischen Erstellung der Auswertung hätte der Anwender zu spezifizieren, welche Art von Join er wünscht.

Aufrechterhaltung der referentiellen Integrität

In der neuen Version von DB2 Version 2, Release 1 lassen sich vom Datenbankadministrator pro Beziehung zwei Integritätsregeln aufstellen, für deren Einhaltung das System sorgt. Diese Regeln werden bei CREATE TABLE oder durch ALTER TABLE spezifiziert.

Für das Löschen können folgende Regeln aufgestellt werden:

RESTRICT: Löschung der übergeordneten Zeile ist nur möglich, wenn keine abhängigen Zeilen vorhanden sind.

CASCADE: Löschung von übergeordneten Zeilen ist möglich. Die davon abhängigen Zeilen werden dabei mit gelöscht.

SET NULL: Die Löschung übergeordneter Zeilen ist möglich. Bei den davon abhängigen Zeilen wird der Fremdschlüssel auf NULL gesetzt.

Beim Einfügen einer Zeile in eine abhängige Tabelle wird geprüft, ob ein gleicher Schlüssel in der übergeordneten Tabelle vorhanden ist. Ist dies nicht der Fall, wird die Einfügung abgewiesen.

Probleme mit der referentiellen Integrität

Beim Verändern eines Fremdschlüssels wird geprüft, ob ein korrespondierender Primärschlüssel vorhanden ist. Bei Veränderung eines Primärschlüssels wird geprüft, ob ein korrespondierender Fremdschlüssel für den alten Primärschlüssel existiert. Ist das der Fall, so kann der Primärschlüssel nicht geändert werden, da die Zeilen in der abhängigen Tabelle dann ohne korrespondierende Zeile in der übergeordneten Tabelle sein würden.

Die in DB2 2.1 implementierten Integritätsregeln bedeuten zwar eine große Erleichterung, doch bestehen weiterhin Probleme. Bezeichnenderweise ist es in DB2 nicht möglich, einen Tabellennamen oder einen Feldnamen direkt zu ändern. Will man zum Beispiel einen Feldnamen in einer Tabelle ändern, so muß man den Inhalt der Tabelle sichern, die Tabelle löschen (DROP), die Tabelle mit dem neuen Feldnamen neu anlegen und die Daten schließlich wieder in die Tabelle laden

Beim Löschen der Tabelle tritt der Cascadeneffekt ein (siehe Integritätsregeln bei DELETE), der beim Katalog für die Löschung implementiert ist. Indices, Views, Synonyme und Berechtigungen, die sich auf die Tabelle beziehen, werden mit gelöscht und müssen nach dem Neuanlegen der Tabelle neu angelegt werden. Dies kann einen hohen Arbeitsaufwand erfordern. (Glücklicherweise gibt es ein Serviceprogramm - nicht von

IBM - , das die genannten Aufgaben zwar nicht überflüssig machen kann, die Durchführung der Arbeiten aber voll automatisiert.)

Ähnliche Probleme ergeben sich auch bei Benutzertabellen, wenn Integritätsregeln implementiert werden. Ein Beispiel ist die Produktnummernänderung. Produktnummern werden im Realfall in vielen Tabellen vorkommen. Auch wenn man die Integritätsregeln vollständig außer Betracht läßt, ist es eine schwierige und fehleranfällige Aufgabe, eine "Namensänderung" korrekt durchzuführen.

In bezug auf die DELETE-Anweisung bedeuten die Integritätsregeln nicht unbedingt eine Verbesserung der Sicherheit der Datenbank. Eine falsche DELETE-Anweisung kann - gerade aufgrund der Integritätsregeln - viele Informationen in der Datenbank zerstören. Ebenso kann die falsche Ausführung einer Umbenennung (zum Beispiel Änderung einer Produktnummer) - verschlimmert durch die Integritätsregeln - eine Korrumpierung der Datenbank bedeuten. Eine Verbesserung könnte darin bestehen, neben dem vorhandenen UPDATE-Befehl einen RENAME-Befehl einzuführen.

Der UPDATE-Befehl bewirkt eine "lokale" Veränderung des Wertes in der angegebenen Tabelle. Die Auswirkungen dieser Veränderung auf andere Tabellen wird durch die Regeln der referentiellen Integrität (siehe weiter oben) reguliert. Der UPDATE-Befehl dient zum Beispiel der Korrektur falscher "Schlüsselwerte".

Der RENAME-Befehl würde - wie der Name schon sagt - dazu dienen, Schlüsselfelder umzubenennen. Er sollte nicht nur den Wert in der angegebenen Tabelle verändern, sondern auch alle logisch identischen Felder in anderen Tabellen, zum Beispiel die Produktnummer in der Produkt-, Auftrags- und Lagertabelle. Dabei kann nicht auf eine Identität des Namens abgestellt werden. Vielmehr müßte bei CREATE TABLE angegeben werden, welche Beziehungen bei RENAME zu berücksichtigen sind (analog zu den oben beschriebenen Integritätsregeln oder in Kombination damit). Der RENAME-Befehl würde die referentielle Integrität "automatisch" aufrechterhalten.

Weiter sollten die Integritätsregeln nicht direkt nach der einzelnen SQL-Anweisung geprüft werden - wie das offenbar der Fall ist - , sondern erst beim "COMMIT-Point". Dadurch wäre es möglich, mehrere SQL-Anweisungen im Zusammenhang auszuführen, die einzeln die referentielle Integrität verletzen, aber insgesamt wieder zu einem integren Status der Datenbank am "COMMIT-Point" führen. Dies würde die referentielle Integrität nicht beeinträchtigen, weil erst nach dem COMMIT die Daten für Zugriffe von außerhalb der Transaktion zur Verfügung stehen.

These 7:

- Die derzeit realisierte Form der referentiellen Integrität (DB2 2.1) erschwert das UPDATE beträchtlich.

Um Erleichterung zu schaffen, sind folgende Modifikationen denkbar:

-Es sollte zusätzlich die Möglichkeit geschaffen werden, die referentielle Integrität alternativ durch Service-Programm im Batch zu prüfen.

-Die Prüfung der referentiellen Integrität sollte am Ende der "Transaktion" erfolgen, nicht - wie zur Zeit offenbar realisiert - nach jeder SQL-Anweisung.

These 8:

- Es sollte zusätzlich eine "RENAME"-Anweisung eingeführt werden, die bei Änderung eines Schlüsselfeldes auch die Schlüsselfelder mitändert, die mit dem Schlüsselfeld - auch indirekt - in Beziehung stehen. Eventuell sollte das Genannte nur für Beziehungen gelten, die die besondere Eigenschaft "RENAME" haben. Kurzfristig sollte ein "RENAME-PROGRAMM" eingesetzt werden, das das Genannte durchführt.