Deutsch English
Blog
Home
Über tdbengine
Newsletter
Download
Helpware
Chat
Dokumentation
Installation
Konfiguration
Erste Schritte
Variablentypen
Laufzeitschalter
Textdateien
Systemfunktionen
Tabellenfunktionen
Indexfunktionen
Volltext-Indizierung
Memos und Blobs
Semaphoren-Konzept
Fehlermeldungen
Tipps für PHP Programmierer
Locking daemon
Einführungskurs
Befehlsreferenz
HOWTO - Wie kann ich...?
Projekte
Links
Benchmarks
Bug Reporting
Supportanfrage
 
Home    Überblick    Suche    Impressum    Kontakt    Mitglieder
Indexfunktionen
Allgemeines zu Indizes
Ein Index ist eine Art Stichwortverzeichnis einer Tabelle, das in einer speziellen Ordnung angelegt wird und dadurch einen sehr schnelle Suche nach Datensätzen erlaubt. Zur Bildung eines solchen Stichwortverzeichnisses können im Prinzip alle Feldtypen verwendet werden, ausgenommen sind hier nur Memos, Blobs und Relationen.

Indizes werden benötigt

  • zur schnelle Suche nach bestimmten (indizierten Feldern)
  • zum (relationalen) Verknüpfen von Tabellen
  • zum geordneten (sortierten) Zugriff auf die Zeilen eine Tabelle
Wird beispielsweise in einer Adresstabelle ein Index über das Feld "Name" erzeugt, so wird eine neue Tabelle mit zwei Feldern angelegt: Das erste enthält den Inhalt des jeweiligen Namenfeldes, das zweite die physikalische Satznummer des zugehörigen Datensatzes. Diese Tabelle wird in einem ganz speziellen Format angelegt, es handelt sich um einen sog. B-Tree (eine hocheffiziente Ordnungs- und Suchstruktur). Und weil die Indizes in externen Dateien abgelegt werden, spricht man bei den Indizes der tdbengine auch von externen Indizes.

Eine Reihe von Indizes wird automatisch angelegt:

Falls die Tabelle ein AUTO-INCREMENT-Feld enthält, wird über dieses Feld eine Index erzeugt (Extension .inr).
Falls die Tabelle ein AUTO-INCREMENT-Feld enthält, wird gemäß der Struktur ein ID-Index erzeugt (Extension .id)
Jedes Link-Feld, das ohne U-Spezifikation in einer Tabelle enthalten ist, führt zu einem Index über dieses Feld (Extension .in1 bis .in9).

Zusätzliche Indizes können ebenfalls in der Strukturdefinition angegeben werden:

ind-name = Name der Indexdatei mit Extension .ind
ind-def = Indexbeschreibung (siehe unten)

Wichtig: Die Namen der Indizes sollten derzeit (ohne Extension) nicht mehr als 8 Zeichen umfassen und nur Buchstaben (ohne Umlaute) enthalten.

Die Indizes des tdbengine
Über jede Tabelle können beliebig viele (in der aktuellen Version 6.2.6 bis zu 15)  Indizes erzeugt werden. Die tdbengine bietet hierarchische Indizes mit bis zu 10 Hierarchiestufen und berechnete Indizes.

Die Definition eines Index erfolgt über eine Indexbeschreibung. Diese hat folgendes Format:

Hierarchischer Index::=Feld-Def{","Feld-Def}.
Feld-Def::=["$"]Feld[":"Zahl]
Feld::=Feldbezeichner|Feldnummer

Berechneter Index::="("Ausdruck")"[":"Zahl]

Beispiele:

Hierarchischer Index: Name,Vorname:1,PLZ
Berechneter Index: (Name+'/'+Vorname):40

Die optionale Angabe : Zahl nach einem Feld (bzw. nach einem Ausdruck) wird nur bei String-Feldern (bzw. bei String-Ausdrücken) ausgewertet und gibt an, wieviele Zeichen des Strings (maximal) in die Indexinformation übernommen werden.

Folgende Einschränkungen für Indexbeschreibungen gelten derzeit (Version 6.2.9):

  • Der Ausdruck eines berechneten Index darf derzeit 40 Zeichen nicht überschreiten.
  • Die Indexinformation (Summe aller Hierarchiestufen) darf maximal 256 Bytes umfassen.
Funktionen zum Erzeugen, Löschen und Auffrischen von Indizes
Hinweis: Die folgenden Funktionen werden nur dann ausgeführt, wenn die Tabelle mit dem Recht "Indizieren" (=8) geöffnet wurde.

Index erzeugen

GenIndex(db : REAL; IndDef : STRING; IndName : STRING) : REAL

db : Tabellenhandle von OpenDB()
IndDef : Indexbeschreibung als String
IndName : Dateiname des Index (ohne Pfad, mit .ind' als Extension)

Rückgabewert:

0 : Funktion konnte nicht ausgeführt werden (Fehlercode mit TDB_LastError)
1..15 : Nummer des neu erzeugten Index

Häufigster Fehler: "Index existiert bereits". Die tdbengine erzeugt keinen Index, wenn eine (Index-)Datei gleichen Namens im Verzeichnis der zu indizierenden Tabelle ist.

Wichtig: Der Index wird immer im gleichen Verzeichnis wie die zugehörige Tabelle abgelegt. Der Name der Indexdatei sollte immer die Extension .ind haben. Die Dateinamen sollten der 8.3-Konvention entsprechen, also xxxxxxxx.ind. Auch Verzeichnisangaben sind nicht zulässig!

In den folgenden Funktionen kann der Parameter Index entweder durch den Indexnamen (mit Extension) oder durch die Indexnummer angegeben werden (gilt erst ab Version 6.2.6, frühere Versionen nur Indexummer bzw. nur Indexname bei FindRec() ).

Index löschen

DelIndex(db : REAL; Index) : REAL

db : Tabellenhandle von OpenDB()
Index: Indexname (ohne Pfad, aber mit Extension) oder Indexnummer

Rückgabewert: 0 = Funktion erfolgreich ausgeführt, sonst Fehlercode

Häufigster Fehler: "Index ist noch in Gebrauch". Solange der Index der aktive Zugriff einer geöffneten Tabelle ist, kann er nicht entfernt werden.

Achtung: Der betreffende Index wird definitiv gelöscht und aus der Tabelle entfernt. Die Funktion sollte mit größter Vorsicht eingesetzt werden: Da Tabellen zu mehreren Projekten gehören können, weiss ein Projekt oft nichts von der Notwendigkeit eines Index in einem anderen Projekt. Nach DelIndex werden alle höheren Indexnummer um 1 dekrementiert.

Index auffrischen

RegenInd(db : REAL; Index) : REAL

db : Tabellenhandle von OpenDB()
Index: Indexname (ohne Pfad, aber mit Extension) oder Indexnummer

Rückgabewert: 0 = Funktion erfolgreich ausgeführt, sonst Fehlercode

Alle Indizes werden automatisch mit der zugehörigen Tabelle aktualisiert, so dass sich im Normalfall keine Notwendigkeit zum Auffrischen ergibt. Allerdings wird im Laufe der Zeit (nach vielen Änderungen an der Tabelle) die Auslastung des zugrunde liegenden B-Trees immer schlechter, so dass dann das Auffrischen eines Index dazu führt, dass

  • die Suchzeit etwas verbessert wird (allerdings kaum messbar)
  • der Platzbedarf auf der Festplatte deutlich reduziert wird.

Alle Indizes auffrischen

RegenAll(db : REAL) : REAL

db : Tabellenhandle von OpenDB()
Rückgabewert: 0 = Funktion erfolgreich ausgeführt, sonst Fehlercode

Damit werden sämtliche Indizes einer Tabelle aufgefrischt.

Achtung: Die Funktionen zur Index-Aufrischung dürfen nicht auf Tabellen angewandt werden, die über ScanRecs() im Minimalmodus erzeugt wurden.

Indexbeschreibung ermitteln

IndDef(db : REAL; Index) : STRING

Zugriffsreihenfolge ermitteln und festlegen
Für jede geöffnete Tabelle kann eine Zugriffsreihenfolge eingestellt werden, die für folgende Funktionen relevant ist: Die Zugriffsreihenfolge ist auch in einer SUB ... ENDSUB Anweisung relevant, wenn hier keine Sortierreihenfolge angegeben wird.

Access(db : REAL[; Index]) : REAL

Ohne Index-Paramter wird die aktuelle Zugriffsreihenfolge zurückgeliefert (erst ab Version 6.2.6):

-2 : Markierungsliste
-1 : Physikalische Ordnung
0 : AUTO-INCREMENT (falls vorhanden)
1: ID-Index (falls vorhanden)
1(2)..15 : entsprechend Indexnummer

Beim Index kann zusätzlich zu den Indexnamen (oder -nummern) noch folgendes angegeben werden:

-2 oder "Markierung"
-1 oder "Nummer"


IndName(db : REAL; Index) : STRING

Liefert den Namen des angegeben Index.

Datensatz über Index suchen

FindRec(db : REAL; SearchStr : STRING [;Index[;Mode : REAL]]) : REAL

db : Tabellenhandle von OpenDB()
SearchStr : gesuchte Information
index : Indexname oder Indexnummer(>=0)
Mode : 0 (Vorgabe) -> Suche nach Eintrag >= SearchStr;  1 -> Suche nach Eintrag = SearchStr

Rückgabewert: 0 -> kein Datensatz gefunden, ansonsten RecNo(db)

Bemerkungen: Der SearchStr muss adäquat zur Index-Beschreibung aufgebaut sein. Enthält eine Komponente ein Komma, so muss diese geklammert werden.

Beispiele:

Index-Beschreibung ="Name,Vorname,Ort"
SearchStr = "Schwalm,Till,München", "Lichtenberg,Franz,(München,Moosach)"

Werden die Informationen vom Anwender geholt, ist eine Klammerung für alle Komponenten sinnvoll:

SearchStr:='('+s_Name+'),('+s_Vorname+'),('+s_Ort+')'

Wird kein Index angegeben, so wird im aktuellen (mittels Access() eingestellten) Index gesucht. Steht der Zugriff nicht auf einem Index (sondern auf Nummer oder Markierung), so erfolgt die Fehlermeldung "Illegaler Zugriff").

Mit dem Modus 0 wird der (bzgl. der Index-Ordnung) kleinste Eintrag gesucht, der gleich oder größer dem Gesuchten ist. Ist hier kein Eintrag vorhanden, so wird der größte Eintrag gesucht, der gleich oder kleiner dem Gesuchten ist. In diesem Modus wird also nur dann 0 zurückgeliefert, wenn die Tabelle komplett leer ist.

Im Modus 1 wird hingegen nur dann ein Wert ungleich 0 geliefert, wenn ein Eintrag gefunden wird, der in allen Komponenten mit der Suche übereinstimmt.

Beispiel:

Tabelle db:
RecNo(db) Name Vorname Ort
1 Meier Franz München
2 Asbacher Edeltraud Frankfurt
3 Grünwalder Antonia Erfurt
4 Meier Hans Hamburg
5 Vogelsang Ottfriede Gelsenkirchen

Index 1 Beschreibung: "Name,Vorname,Ort"
Index 2 Beschreibung: "(Name+'/'+Vorname)"

Index 1 (intern)
Index Information RecNo(db)
Asbacher,Edeltraud,Frankfurt 2
Grünwalder,Antonia,Erfurt 3
Meier,Franz,München 1
Meier,Hans,Hamburg 4
Vogelsang,Ottfriede,Gelsenkirchen 5


FindRec(db,"Meier,Franz,München",1,0) -> 1
FindRec(db,"Meier,Franz,München",1,1) -> 1
FindRec(db,"Meier,Franz",1,0) -> 1
FindRec(db,"Meier,Franz",1,1) -> 0

Index 2 (intern)
Index Information RecNo(db)
Asbacher/Edeltraud 2
Grünwalder/Antonia 3
Meier/Franz 1
Meier/Hans 4
Vogelsang/Ottfriede 5


FindRec(db,"Meier/Hans",2,0) -> 4
FindRec(db,"Meier/Hans",2,1) -> 4
FindRec(db,"Meier",2,0) -> 1
FindRec(db,"Meier",2,1) -> 0

Filter setzen
Durch einen Index wird eine Tabelle in eine Ordnung gebracht. Mit einem Filter wird bezüglich dieser Ordnung eine zusammenhängende Teilmenge (ein Ausschnitt) aus der Tabelle definiert.

SetFilter(db : REAL; VON [, bis] : STRING) : REAL

db : Tabellenhandle von OpenDB()
von, bis : Indexinformation gemäß Indexbeschreibung

Rückgabewert: Immer 0

SetFilter() ist nur wirksam, wenn der Zugriff auf einen Index gesetzt wurde, also erst nach Access(db,...).

Ein Filter ist solange aktiv, bis er

  • mit SetFilter(db,'') aufgehoben wird, oder
  • die Primärtabelle gewechselt wird
Ist ein Filter aktiv, führt FirstRec ein FindRec(db,von) aus, liefert aber nur einen Wert, wenn der gefundene Datensatz gleich oder größer dem Inhalt von "von" ist. Entsprechendes gilt für LastRec. NextRec bzw PrevRec liefern nur dann Ergebnisse, wenn die gefundenen Werte im aufgespannten Bereich liegen. Auch SUB liefert nur Datensätze aus diesem Bereich.

Der Parameter bis kann nur weggelassen werden, wenn die zugehörige Indexbeschreibung ausschließlich String-Felder enthält:

SetFilter(db,von) steht dann als Abkürzung für SetFilter(db,von,von+chr(255)).

Bei einem hierarchischen Index werden nicht angegebene Komponenten bei von mit dem kleinsten, bei bis mit dem größten möglichen Wert aufgefüllt.

Die Filter-Automatik der tdbengine
Bei der Bearbeitung von Selektionen versucht die tdbengine die zu lesende Datenmenge und damit den Selektionsaufwand zu minimieren, indem sie alle vorhandenen Indizes daraufhin untersucht, ob ein passender Filter gesetzt werden kann. Diese Automatik arbeitet unabhängig von der Reihenfolge der logischen Operationen und auch unabhängig von der verkürzten Logikauswertung.

Die Automatik wird abgeschaltet, wenn zum Zeitpunkt der Selektion

  • der Zugriff über die Markierungsliste erfolgt, oder
  • der Zugriff auf einen anderen Index als den .inr (über die Autonummern) gesetzt ist.
Beispiel für die Arbeitsweise der Filter-Automatik:
[STRUCTURE]
field_1=Name,STRING,40
field_2=Vorname,STRING,30
field_3=Strasse,STRING,40
field_4=PLZ,STRING,5
field_5=Ort,STRING,30
[INDEX]
index_1=adr_name.ind:Name,Vorname
index_2=adr_plz.ind:PLZ,Ort


Selektion Index Filter von ... bis
$Name like "Meier" adr_name.ind meier
$Name like "Meier*" and $Vorname like "Hans" adr_name.ind meier,hans
$PLZ from "70000" to "79999" adr_plz.ind 70000 ... 79999,chr(255)+chr(255)...
$Name like "*gruber" and $PLZ like "8*" adr_plz.ind 8
( "*gruber" erlaubt keinen Filter)
$Name like "hinter*meier*" and $PLZ like "8*" adr_name.ind hinter
(4 Zeichen hei "hinter" gegenüber 1 Zeichen bei "8")

Die Filter-Automatik sorgt dafür, dass die Funktion SetFilter nur in wenigen Spezialfällen eingesetzt werden muss.

Siehe auch:





tdbengine Anwendungen im Web:

Open-Source Web CMS


Open-Source Bug-Tracking


Free wiki hosting

Open-Source Wiki-System

Kostenloses Foren-Hosting

Diät mit tdbengine 8-)

tdbengine chat
irc.tdbengine.org
#tdbengine

   Copyright © 2003-2004 tdb Software Service GmbH
   Alle rechte vorbehalten. / All rights reserved
   Letzte Änderung: 04.05.2004


ranking-charts.de

Programmers Heaven - Where programmers go!