Index in der Datenbank
Objekte sind in der Datenbank in Collections zusammengefasst - das sind einerseits die Root_Entry-Point-Collections des ClassiX®-Systems, andererseits Datenfelder der Objekte vom Typ COLLECTION, REL_M1 oder REL_MN.
Zu jeder Collection können Datenbank-Indexe aufgebaut werden (auch mehrere). Der Index bezieht sich auf ein Datenfeld der in der Collection enthaltenen Objekte oder auf eine Funktion.
Ein Index bewirkt, dass
- Objekte mit Queries (die sich auf das indizierte Datenfeld / die Funktion beziehen) sehr viel schneller aufgefunden werden
- die Iteration mit einem Indexpfad (der sich auf das indizierte Datenfeld / die Funktion bezieht) effektiver wird.
Ein Datenbank-Index wird automatisch aktualisiert, wenn sich die Werte eines betroffenen Datenfeldes ändern, wenn Objekte aus der indizierten Collection entfernt oder neue eingefügt werden.
Für den Aufbau eines Datenbank-Index gelten folgende Einschränkungen:
- Indexe können für Objekte ab Klasse CX_EXPANDABLE gebildet werden. Nur Objekte dieser und aller davon abgeleiteten Klassen besitzen die Fähigkeit, dass der Index auch tatsächlich automatisch aktualisiert wird, wenn sich die Objekte verändern.
- Ein Index wird dann automatisch aktualisiert, wenn ein die Ordnung innerhalb des Index berührendes Datenfeld mit Put oder DrainWindow verändert wird.
Ein Index kann nicht automatisch aktualisiert werden, wenn die Verbindung zum betroffenen Objekt verloren geht, z.B wenn value object Put(a.b) durch object Get(a) -> x, value x Put(b) ersetzt wird. Das gilt immer für einen Index "a.b", kann aber auch für einen Index "a" zutreffen, wenn b die Ordnungsrelation von a mitbestimmt (-> konkretes Beispiel).
- Um den Aufwand für die Index-Aktualisierung für alle die Datenfelder zu sparen, wo voraussichtlich niemals ein Index gebildet wird, sind die indizierbaren Datenfelder in den Data-Dictionaries (DDI) gekennzeichnet. Der Hinweis auf Indizierbarkeit ist auch in der Dokumentation zum CyberEnterprise® zu finden.
-
Indexe können auch über dynamische Datenfelder gebildet werden. Die Vermittlung an den Index-Mechanismus der Datenbank ObjectStore ist kompliziert und muss deshalb mit Angaben im System-Dictionary unterstützt werden - siehe Direktive Index.
-
Der Typ des Datenfeldes, über das ein Index gebaut werden soll, muss eine Ordnungsrelation definieren. Das ist für STRING, INTEGER, SHORT usw. der Fall; ebenso für alle Klassen, für die auf der InstantView®-Ebene die Vergleichsoperatoren <, > und = definiert sind (d.h. die Klasse besitzt die virtuelle Funktion Compare).
-
Ein Index kann nur über solche Funktionen aufgebaut werden, die im ClassiX®-System als Query-Functions angemeldet sind. Sie sind immer parameterlos! Das ist eine Vorgabe der Datenbank ObjectStore: Die Ordnungsrelation soll allein vom Zustand des Objekts abhängen. Das bedeutet, dass bei Änderungen bestimmter Datenfelder ein Index über eine Query-Funktion nachgeführt werden muss. Damit das automatisch geschieht, wird die Query-Funktion im DDI des betreffenden Datenfeldes (oder der Datenfelder) eingetragen (-> konkretes Beispiel).
-
Ein Index kann sich auch indirekt - über einen Zugriffsausdruck - auf ein Datenfeld beziehen - Beispiel: "owner.uniqueID".
Gegenüber den Möglichkeiten eines Zugriffsausdrucks auf der InstantView®-Ebene gelten beim Aufbau eines Datenbank-Indexes Einschränkungen.
-
Ein Index über einen InstantView®-Zugriffsausdruck kann mittels der Pseudo-Funktion Retrieve gebildet werden. Die oben genannten Einschränkungen gelten dann nicht. Solche Indexe werden im allgemeinen nicht mehr automatisch aktualisiert.
Die Ausnahme: Das betroffenen Objekt bzw. die Objekte besitzen eine PrePostUpdate-Funktion, die im DDI mit den entsprechenden Datenfeldern verbunden ist und den Index nachführt (-> konkretes Beispiel).
Sonst kann ein "Retrieve(... )"-Index mit Hilfe des Index-Manager explizit nachgeführt werden, d.h. im InstantView®-Code muss die Indexaktualisierung programmiert werden.
Zusammenfassung, wie im ClassiX®-System die Aktualisierung eines Datenbank-Indexes automatisiert wird:
was wird indiziert ... | damit ein Index wird automatisch nach geführt wird ... |
---|---|
"normales" Datenfeld | im DDI mit INDEXABLE kennzeichnen |
dynamisches Datenfeld | Index(slotName, n) im .ini-File eintragen |
Query-Funktion ist abhängig von "normalen" Datenfeldern | im DDI-Eintrag QUERYFUNCTION(QueryFunction) angeben |
komplizierte Abhängigkeit eines Retrieve-Index oder eines Index über Query-Funktion von bestimmten Datenfeldern | im DDI oder (für dynmische Datenfelder) im .ini-File PrePostUpdate-Funktion eintragen |
Ein Datenbank-Index wird aufgebaut mit Anweisung AddIndex. Anweisung DropIndex entfernt einen Datenbank-Index wieder.
Ein Übersicht über alle in der Datenbank existierenden Indexe liefert der Index-Manager.
Wesentliche Eigenschaften eines Datenbank-Indexes werden beim Aufbau durch die Angabe von Optionen vorgegeben:
Option | Bedeutung | weitere Hinweise |
---|---|---|
ORDERED | Index beruht auf einer Ordnungsrelation (<, > und = sind definiert) | ohne ORDERED muss nur = definiert sein, der Index hat den Charakter einer Hash-Tabelle |
NO_DUPLICATES | ObjectStore generiert eine Fehlermeldung, wenn zwei Indexeinträge mit dem gleichen Wert entstehen | |
COPY_KEY | der Wert des Datenfeldes wird in den Index kopiert | siehe unten bzw. Direktive IndexCopy im .ini-File |
POINT_TO_KEY | der Wert des Datenfeldes wird nicht in den Index kopiert, die Index-Struktur verweist auf den Wert im Objekt |
Vor- und Nachteile der Optionen COPY_KEY versus POINT_TO KEY sind:
Option | Pro | Contra |
---|---|---|
COPY_KEY | hohe Geschwindigkeit bei der Suche, weniger Locking-Konflikte | höherer Aufwand bei der Index-Nachführung, wenn sich der Wert eines betroffenen Datenfeldes ändert |
POINT_TO_KEY | geringere Geschwindigkeit bei der Suche, höhere Wahrscheinlichkeit von Locking-Konflikten | etwas kleinerer Aufwand bei der Index-Nachführung wenn sich der Wert eines betroffenen Datenfeldes ändert |
Schlussfolgerung: | Bei den im ClassiX®-System möglichen Datenbank-Indexen überwiegen die Vorteile von COPY_KEY ! |
Was wird bei Option COPY_KEY kopiert?
Mit der Option COPY_KEY wird ObjectStore angewiesen, die im Index genannten Schlüsseldatenfelder zu kopieren. Soweit es sich um Objekte handelt, ist dies eine flache Kopie. Dies ist das Standard-Verhalten.
Im ClassiX® .ini-File kann mit
IndexCopy(DEEP)
tiefes Kopieren beim Aufbau der Indexe verlangt werden.
Tiefes Kopieren bezieht sich
- auf Datenfelder vom Typ STRING (durch die Klasse CXB_STRING) repräsentiert. Jetzt wird nicht nur das CXB_STRING-Objekt, sondern auch die Zeichenkette selbst in den Index kopiert. Dies verbessert die Geschwindigkeit bei Queries und reduziert Locking-Konflikte.
- Indexe über dynamische Datenfelder vom Typ "Objekt" - z.B. CX_DATE, CX_TIME, CX_NUMERIC ...
Die interne Behandlung vereinfacht sich, ohne dass dies Auswirkung auf Performance und Concurrency hat.
Über IndexCopy(FLAT) kann konfiguriert werden, dass Indizies ihre Werte nur flach kopieren.
Ist nichts angegeben, dann wird IndexCopy(DEEP) angenommen.
Achtung: vor Dll-Version 212701 war das Verhalten bei fehlender Angabe undefiniert.
Achtung!
Ein Wechsel FLAT -> DEEP oder umgekehrt ist nur möglich, nachdem vorher alle Datenbank-Indexe gelöscht wurden. Erst danach darf das .ini-File verändert werden, und alle Indexe müssen neu aufgebaut werden. Wird diese Vorgehensweise nicht eingehalten, droht Datenverlust!