This commit is contained in:
Oliver Lehmann 1989-06-16 11:31:59 +00:00
parent d3a00367c6
commit 964b85169c
4 changed files with 5334 additions and 0 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,544 @@
.ds RH \f3ZIP\f1
.ds LH Anwendung
.ds CH - % -
.bp
.LP
.NH 2
.ft B
Eingabegenerator ZIP
.br
- Vers. 2.1 *
.ft R
.LP
.sp 10
.NH 3
.ft B
Einleitung
.ft R
.LP
Der vorliegende Eingabegenerator ist den Bedingungen von
\*(xx\-Versionen angepasst, f\o'u"'r die eine
.ft B
termcap
.ft R
und das
Softwarepaket
.ft B
curses
.ft R
verf\o'u"'gbar sind.
Da ZIP als Hilfe f\o'u"'r die Eingabe und Anzeige von Daten
in der Umgebung von AMX- und EQUEL-Programmen entworfen wurde,
soll nachfolgend die Anwendung auch an solchen Beispielen
gezeigt werden.
.LP
Die Erstellung einer ZIP-Prozedur erfolgt in drei Schritten:
.IP 1.
Mit dem Editor wird eine Maske entworfen, die deckungsgleich
sp\o'a"'ter auf dem Bildschirm abzubilden ist. Variablenfelder
werden durch # eingeleitet, die Anzahl der nachfolgenden Zeichen
bis zum Leerzeichen bzw. Newline (auch EOF)
oder einem beliebigen Begrenzungszeichen
legt die Stelligkeit fest (einschliesslich #).
Bei Gleitkommazahlen bestimmt der Punkt die Konvertierungsvorschrift.
.IP 2.
Die Textmaske (Filename: vorgeschlagenes Postfix _m) wird
einschliesslich m\o'o"'glicher steuernder Flags
als Argument f\o'u"'r das Kommando
.ft B
zip
.ft R
angegeben und ein C-Quellfile generiert.
.IP 3.
Die Verbindung zwischen Maske und Variablen ergibt sich
aus dem Dialog. Die Flags -hp ziehen zus\o'a"'tzliche Fragen
f\o'u"'r Hilfen bzw. Pr\o'u"'fungen nach sich.
Der C-Compiler wird automatisch gerufen, bei Flag -l erfolgt
die Einordnung in eine Arbeits\%bib\%lio\%thek.
.LP
Bei Verwendung des Flag -z wird ein Zeilenoffset ausgegeben.
Er berechnet sich aus der Anzahl der Newlines + EOF im Ausgangsfile.
Mit diesem Offset soll der Entwurf des Gesamtbildes auf dem
Schirm kontrolliert werden.
.LP
Bevor eine ZIP-Prozedur im Programm genutzt werden kann, ist
die Initia\%lisie\%rungs\%prozedur
.ft B
initzip()
.ft R
zu rufen - sie
ini\%tiali\%siert auch die Verwendbarkeit der
.ft B
curses
.ft R
-Makros bzw.
Prozeduren. Die \o'u"'blichen Ausgaben zu stdout (printf, write,
putchar usw.) d\o'u"'rfen innerhalb des G\o'u"'ltigkeitsbereiches
des sogenannten "Standard-Screen" (stdscr) nicht verwendet
werden, weil dann Konsistenzprobleme auftreten.
Daf\o'u"'r stehen die curses-Makros (addstr(), addch()) zur
Verf\o'u"'gung.
.br
.ft B
Anmerkung:
.ft R
Zum Binden des gesamten Programmes (AMX, EQC u.a.) sind
die Bibliotheken libcurses.a und libzip.a einzu\%ziehen.
.LP
Die direkte Einordnung des Generators in das Datenbanksystem
unter Nutzung der System-Relation "attribute" ist
vorl\o'a"'ufig nicht geplant.
Die Praxis zeigt, dass die Eingabe und Korrektur aller
Dom\o'a"'nen in einem Menue die Ausnahme ist - als
weiteres Problem steht dann, in welcher Reihenfolge
die F\o'u"'hrungstexte den Spalten
zugeordnet werden sollten. Hierzu w\o'a"'re
wieder ein Dialog oder eine Zuordnung in der Phase des Editierens
der Maske notwendig.
Es ist in der Regel so, dass erst in Abh\o'a"'ngigkeit vom Wert des
Schl\o'u"'ssels entweder vom Programm oder vom
Bedienenden entschieden wird, wie sich der weitere
Ablauf gestaltet ("append", "replace" oder "delete") bzw.
die Dom\o'a"'nen anderer Relationen einzubeziehen sind.
.NH 3
.ft B
Realisierung
.ft R
.LP
ZIP wird durch "make all" im Directory "../../src/zip"
installiert. Das Kommando zip wird in "../../bin" eingeordnet.
Ruft man zip ohne Parameter, wird eine Kurzinformation
zur Anwendung gegeben (in "../../man/zip").
Im Directory "../src/zip" ist ein Directory "tut" enthalten,
an dem man sich analog dieser Dokumentation orientieren kann.
.LP
Die verwendete Relation "anschrift" hat folgende Struktur:
.DS L
Relation: anschrift
---------
Besitzer: ing_db
Tupellaenge: 199
Verfallsdatum: Wed Mar 30 15:21:36 1988
Tupelanzahl: 99
Speicherstruktur: ISAM
Relationentyp: Nutzerrelation
.DE
.sp 1
.DS L
Domaenname Typ Laenge Schluessel
-------------------------------------------
bn i 4 1
ans1 c 40
ans2 c 40
ans3 c 30
ort c 30
plz c 5
kubez c 48
bezirk i 2
-------------------------------------------
.DE
.LP
Zur Veranschaulichung der Verfahrensweise folgendes
AMX-Programm:
.nf
-------------------------------------------------------------
## shared hardsoft
/* Eingabe und Korrektur von Anschriften */
## long BN;
## char ANS1[40]; /* 1.Zeile Anschrift */
## char ANS2[40]; /* 2.Zeile Anschrift */
## char ANS3[30]; /* 3.Zeile Anschrift, Strasse/Psf. */
## char ORT[30]; /* Ort */
## char PLZ[5]; /* Postleitzahl */
## char KUBEZ[48]; /* Kurzbezeichnung Anschrift */
## int BEZIRK; /* individueller Bezirksschluessel */
amx()
{
int flag;
int clr;
int zl;
initzip(); /*Initialisierung von curses und zip*/
## open anschrift
do
{
BN = 0;
ANS1[0] = ANS2[0] = ANS3[0] = ORT[0] = '\\0';
PLZ[0] = '\\0';
KUBEZ[0] = '\\0';
clr = 0;
if (!ansbn(clr++, 0)) break; /*Schirm wird gloescht,*/
if (!BN) break; /*dr anschliessend erhoeht*/
flag = 0;
## scan anschrift $bn=BN (ANS1=$ans1,ANS2=$ans2,ANS3=$ans3,
## ORT=$ort,PLZ=$plz,KUBEZ=$kubez,BEZIRK=$bezirk)
## {
++flag;
if (!ansein(clr, 1)) break; /*kein Schirm loeschen,*/
/*alle Variablen erst anzeigen*/
## replace ($bn=BN,$ans1=ANS1,$ans2=ANS2,$ans3=ANS3,
## $ort=ORT,$plz=PLZ,$kubez=KUBEZ,$bezirk=BEZIRK)
## }
if (!flag)
{
if (!ansein(clr, 1)) continue;
## append anschrift ($bn=BN,$ans1=ANS1,$ans2=ANS2,
## $ans3=ANS3,$ort=ORT,$plz=PLZ,$kubez=KUBEZ,$bezirk=BEZIRK)
}
}
while (BN);
## commit
## close anschrift
}
-------------------------------------------------------------
.fi
.LP
Als Eingabe- bzw. Korrekturprozeduren kommen ansbn() und ansein() vor.
Mit der Trennung
in zwei Masken bzw. Prozeduren
wird vermieden, dass ansein() bei BN = 0 noch Werte abfordert
und das gleiche Programm zum Anf\o'u"'gen neuer Tupel bzw. zum
\o'A"'ndern vorhandener Verwendung findet. Im ersten Schritt
werden die Masken
.ft B
ansbn_m
.ft R
und
.ft B
ansein_m
.ft R
mit dem Editor aufgestellt,
dabei ist zu beachten, dass in den Zeilen, bei denen mit
F\o'u"'hrungstexten begonnen wird, ganz links kein Leerzeichen
steht - f\o'u"'hrende Leerzeichen werden nicht ausgegeben:
.DS L
.ft B
Maske ansbn_m:
.ft R
Erfassg./Korr. von Anschriften ==> Abbruch: Betriebsnummer = 0
Betriebsnummer(8-St.): #9999999<
.DE
.DS L
.ft B
Maske ansein_m:
.ft R
Anschrift-Betriebsbezeichnung1: #aaaaaaaaaaaaaaaaaaaaaaaaa..a<
..........Betriebsbezeichnung2: #aaaaaaaaaaaaaaaaaaaaaaaaa..a<
..........Strasse/Nr. : #aaaaaaaaaaaaaaaaaaaaaaaaaaaa<
..........Ort : #aaaaaaaaaaaaaaaaaaaaaaaaaaaa<
..........Postleitzahl : #aaa<
Kurzbezeichnung: #aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa<
Bezirk : #9<
.DE
In den ersten beiden Zeilen wurden, um eine bessere Darstellung
zu erreichen, einige a ausgeblendet (entspricht ..).
.LP
.ft B
Ablauf:
.ft R
.LP
Der Eingabe-Generator wird mit
.br
.ft B
zip
.ft R
-pl LIBTUT ansbn
.br
gerufen.
.nf
Darstellung des Dialogs:
-------------------------------------------------------------
+--------------------------------+
| EINGABE-GENERATOR >>> ZIP <<< |
| Version 2.1 (curses) 01.02.89 |
| EVK Olbernhau |
+--------------------------------+
Der Abfragezyklus bezieht sich jeweils auf eine Variable!
Zur Orientierung werden die Texte der Maske mit ausgegeben.
Erfassg./Korr. von Anschriften ==> Abbruch: Betriebsnummer = 0
Betriebsnummer(8-St.):
>>>Datentyp (i/l/c/f/d) > l
>>>vereinbarter Name (Feld mit []) > BN
>>>mit Korrekturmoeglichkeit?(j/n) > j
>>>Name Pruefprozedur mit () u.Arg.> przk()
>>>Pruef-Art:Zei.=z/Wort=w > w
>>>Hilfe einordnen? (j/n) > j
>>>Hilfe-Art: Text=t / Prozedur=p > t
>>>Name File f. Hilfe-Text m. (z,s) > bnhlp(3,15)
9999999<
Okay? >j
-------------------------------------------------------------
.fi
.LP
Zur Orientierung im Dialog gibt ZIP alle F\o'u"'hrungstexte
entsprechend der Textmaske mit aus.
.LP
Parallel zum Dialog wird das File ansbn_i angelegt:
.DS I
-pl LIBTUT ansbn
long BN j przk() w bnhlp(3,15) t
.DE
.LP
Die Pr\o'u"'fung der Statistik-Betriebsnummer erledigt die Prozedur przk():
.nf
-------------------------------------------------------------
/* Pruefziffernkontrolle Modul 11 (8-stellig) */
przk(pn) long *pn;
{
long nr;
int bew[8];
int erg, sg, i, divr, anr, pz, p;
nr = *pn;
bew[0] = 0;
bew[1] = 4;
bew[2] = 8;
bew[3] = 5;
bew[4] = 10;
bew[5] = 9;
bew[6] = 7;
bew[7] = 3;
p = nr % 10;
sg = 0;
for (i = 0; i < 8; i++ )
{
anr = nr % 10;
erg = anr * bew[i];
sg = sg + erg;
nr = nr / 10;
}
divr = sg % 11;
switch(divr)
{
case 0 : pz = 5;
break;
case 2 : pz = 4;
break;
case 3 : pz = 9;
break;
case 4 : pz = 3;
break;
case 5 : pz = 8;
break;
case 6 : pz = 2;
break;
case 7 : pz = 7;
break;
case 8 : pz = 1;
break;
case 9 : pz = 6;
break;
default: pz = 0;
}
if (p == pz) return(1);
else return(0);
}
-------------------------------------------------------------
.fi
.LP
Der R\o'u"'ckkehrcode dieser Prozedur, die ebenfalls in LIBTUT steht,
wird ausgewertet (1 ist TRUE, 0 ist FALSE). Der Return-Code 0
veranlasst nach einem Hupton zur erneuten Eingabe (Kursor
auf Feldanfang), die Eingabe von Fragezeichen (?) f\o'u"'hrt zur
Ausgabe der
Hilfe "pruefzifferngesichert" - der Text dazu steht im File bnhlp,
das bei der Generierung eingezogen wird.
Die Prozedur ansein() wird mit
.br
zip -a 3 -hl LIBTUT ansein
.br
generiert.
Der Dialog l\o'a"'uft wie folgt ab:
.nf
-------------------------------------------------------------
+--------------------------------+
| EINGABE-GENERATOR >>> ZIP <<< |
| Version 2.1 (curses) 01.02.89 |
| EVK Olbernhau |
+--------------------------------+
Der Abfragezyklus bezieht sich jeweils auf eine Variable!
Zur Orientierung werden die Texte der Maske mit ausgegeben.
Anschrift-Betriebsbezeichnung1:
>>>Datentyp (i/l/c/f/d) > c
>>>vereinbarter Name (Feld mit []) > ANS1[40]
>>>mit Korrekturmoeglichkeit?(j/n) > j
>>>Hilfe einordnen? (j/n) > n
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa<
..........Betriebsbezeichnung2:
>>>Datentyp (i/l/c/f/d) > c
>>>vereinbarter Name (Feld mit []) > ANS2[40]
>>>mit Korrekturmoeglichkeit?(j/n) > j
>>>Hilfe einordnen? (j/n) > n
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa<
..........Strasse/Nr. :
>>>Datentyp (i/l/c/f/d) > c
>>>vereinbarter Name (Feld mit []) > ANS3[30]
>>>mit Korrekturmoeglichkeit?(j/n) > j
>>>Hilfe einordnen? (j/n) > n
aaaaaaaaaaaaaaaaaaaaaaaaaaaa<
..........Ort :
>>>Datentyp (i/l/c/f/d) > c
>>>vereinbarter Name (Feld mit []) > ORT[30]
>>>mit Korrekturmoeglichkeit?(j/n) > j
>>>Hilfe einordnen? (j/n) > n
aaaaaaaaaaaaaaaaaaaaaaaaaaaa<
..........Postleitzahl :
>>>Datentyp (i/l/c/f/d) > c
>>>vereinbarter Name (Feld mit []) > PLZ[5]
>>>mit Korrekturmoeglichkeit?(j/n) > j
>>>Hilfe einordnen? (j/n) > n
aaa<
Kurzbezeichnung:
>>>Datentyp (i/l/c/f/d) > c
>>>vereinbarter Name (Feld mit []) > KUBEZ[48]
>>>mit Korrekturmoeglichkeit?(j/n) > j
>>>Hilfe einordnen? (j/n) > n
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa<
>>>Datentyp (i/l/c/f/d) > i
>>>vereinbarter Name (Feld mit []) > BEZIRK
>>>mit Korrekturmoeglichkeit?(j/n) > j
>>>Hilfe einordnen? (j/n) > j
>>>Hilfe-Art: Text=t / Prozedur=p > t
>>>Name File f. Hilfe-Text m.(z,s) > bezhlp(15,3)
9<
Okay? >>j
-------------------------------------------------------------
.fi
.LP
Die nach > stehenden Eingaben sind jeweils mit <CR> (Carriage Return)
abzuschliessen.
Folgendes i-File entsteht:
.DS I
-a 3 -hl LIBTUT ansein
char ANS1[40] j n n
char ANS2[40] j n n
char ANS3[30] j n n
char ORT[30] j n n
char PLZ[5] j n n
char KUBEZ[48] j n n
int BEZIRK j n bezhlp(15,3) t
.DE
.LP
Es w\o'a"'re denkbar, die PLZ mit "isdigit()" zu pr\o'u"'fen, in Abweichung
zu oben entst\o'u"'nde das i-File:
.DS I
-a 3 -phl LIBTUT ansein
char ANS1[40] j n n
char ANS2[40] j n n
char ANS3[30] j n n
char ORT[30] j n n
char PLZ[5] j isdigit() z
char KUBEZ[48] j n n
int BEZIRK j n bezhlp(15,3) t
.DE
.LP
Beachten sie, dass \et als Trennzeichen steht.
Bei \o'A"'nderungen im *_i-File
d\o'u"'rfen die
Trennzeichen nicht versehentlich gel\o'o"'scht
werden!
.LP
Es wird bei der Erzeugung der Ein-/Ausgabe-Prozedur
davon ausgegangen, dass die C-Variablen an
Spalten bestimmter Relationen \o'u"'bergeben
bzw. von diesen \o'u"'bernommen werden. Deshalb sind
die C-Variablen grunds\o'a"'tzlich global de\%kla\%riert,
entsprechend erwartet die erzeugte Prozedur eine
globale Deklaration zur Wert-\o'U"'bergabe/-\o'U"'bernahme.
F\o'u"'r alle zu realisierenden Konvertierungen werden die
Prozeduren (im Sinne von Parameter-Prozeduren)
aus /usr/lib/libzip.a verwendet.
Die manuelle Ersetzung
der Funktionsprozeduren aus der Standard-Bibliothek von
C (libc.a) f\o'u"'hrt zu Fehlern.
.LP
Die Reihenfolge der Objekte in
der Arbeits-Bibliothek (hier LIBTUT) spielt eine Rolle,
sofern Pr\o'u"'fprozeduren verwendet werden (nach der ZIP-Prozedur !).
Die Arbeits-Bibliothek muss im Bindekommando
vor /usr/lib/libzip.a stehen.
.LP
Pruefprozeduren werden in Anlehnung an
die Funktionen aus "ctype" (isdigit(), isascii() usw.) so
ge\%staltet, dass der Rueckkehrcode 1 fuer TRUE und
0 f\o'u"'r FALSE liefert. Das gilt sowohl f\o'u"'er Prozeduren
die zeichenweise (z) als auch f\o'u"'r solche, die
wortweise (w) pr\o'u"'fen.
Das header-File <ctype.h> wird f\o'u"'r ZIP-Prozeduren
standardm\o'a"'ssig eingezogen.
.LP
Als kleine zus\o'a"'tzliche Hilfe von ZIP steht eine
Menue-Prozedur
.ft B
menzip()
.ft R
zur Verf\o'u"'gung, die ein im main() vereinbartes Zeichenkettenfeld
auf w\o'a"'hlbaren Positionen invers ausgibt und die
angeklickte Zeile (1..n) als R\o'u"'ckkehrwert liefert
(s. Teil III, Beispiel "Terminkontrolle").

View File

@ -0,0 +1,597 @@
.ds LH Anwendung
.ds RH \f3ZUGRIFF\f1
.ds CH - % -
.bp
.NH 2
.ft B
Zugriffsmethoden und **
.br
Datenlokalisierung
.ft R
.LP
.sp 10
.NH 3
.ft B
Einleitung
.ft R
.LP
\*(yy\ unterst\o'u"'tzt mehrere Zugriffsmethoden,
deren sinnvoller Einsatz dem Projektanten
und dem Datenbankadministrator \o'u"'berlassen wird
und die Zuordnung von Datenbanken
und Relationen in eine hierarchische \*(xx\-File-Struktur.
.LP
Diese Kapitel beschreibt die Funktionsweise
der Zugriffsmethoden und gibt damit ,weiterf\o'u"'hrend
zum vorangegangenen, eine
Anleitung zu ihrem effektiven problembezogenem Einsatz.
Ausserdem werden die Teile des \*(yy\-Filesystems
beschrieben, die den anwendungsbezogenen Aufbau
mountbarer Filesysteme erm\o'o"'glichen.
.NH 3
.ft B
Grundkonzepte von \*(yy
.ft R
.NH 4
.ft B
Seitenkonzept und Tupeldarstellung
.ft R
.LP
Alle Zugriffsmethoden legen den Datenbestand
einer Relation in \*(xx\-Files ab.
Das File ist generierungsabh\o'a"'ngig in Seiten von 512-Byte
(\*(xx\ Version 7) oder 1KByte L\o'a"'nge
unterteilt. Jedes File f\o'u"'r eine
Relation besteht aus einer ganzen Anzahl von Seiten,
mindestens aber aus einer.
.LP
Jede Seite enth\o'a"'lt Tupel der Relation
und zwar so, dass jedes Tupel vollst\o'a"'ndig auf einer Seite
untergebracht ist.
.LP
Ein Tupel kann gew\o'o"'hnlich oder komprimiert gespeichert
werden:
Als gew\o'o"'hnlich gespeichertes Tupel wollen wir eine Speicherung verstehen,
wo jedes Attribut des Tupel genau soviele Bytes
belegt, wie beim create der Relation
als Formatl\o'a"'nge f\o'u"'r die entsprechenden Dom\o'a"'nen
definiert wurde.
Bei den Dom\o'a"'nen des Typs c (character) wird h\o'a"'ufig der
Fall eintreten, dass deren Attribute den verf\o'u"'gbaren Speicherplatz
nicht voll ausf\o'u"'llen, indem sie ab einer bestimmten
Position nur noch Leerzeichen enthalten.
Als eine komprimierte Speicherung eines Tupel
verstehen wir eine solche,
bei der Attribute von c-Dom\o'a"'nen um diese rechten Leerstellen
verk\o'u"'rzt werden (das Ende des relevanten Teils
des Attributes wird durch ein zus\o'a"'tzliches '\e0'-Byte markiert ! ).
Als Spreizen einer Relation wollen wir die Transformation
einer komprimierten in die gew\o'o"'hnliche Darstellung
verstehen.
.LP
F\o'u"'r gew\o'o"'hnlich dargestellte Relationen kann man die auf einer
Seite unterbringbaren Tupel berechnen als
.DS I
512 - 12
Tupel pro Seite = ggZ (--------------------)
Tupell\o'a"'nge + 2
(Tupell\o'a"'nge in Byte,
ggZ: gr\o'o"'sste ganze Zahl von )
.DE
Man sieht, dass pro Seite generell 12
Bytes und pro Tupel 2 Byte Verwaltungsplatz
ben\o'o"'tigt werden.
.LP
Analog kann man sich ausrechnen, wieviel Restplatz
auf jeder Seite frei bleibt, wenn die Tupell\o'a"'nge
so gew\o'a"'hlt wird, dass ein ganzes Vielfaches von
ihr ( + 2 ! ) die Seite nicht ausf\o'u"'llt.
Maximal darf die Tupell\o'a"'nge 498 Bytes betragen
(pro Seite dadurch also ein Tupel !).
Die Beziehungen f\o'u"'r 1024-Byte-Seiten k\o'o"'nnen
mit den gleichen absoluten Werten berechnet werden.
.LP
Aus der Anzahl der Tupel und den auf einer Seite unterbringbaren,
kann der, f\o'u"'r eine Relation insgesamt n\o'o"'tige Speicherplatz
ausgerechnet werden.
.LP
F\o'u"'r komprimiert dargestellte Relationen
muss man eigene Absch\o'a"'tzungen verwenden.
.LP
Wir bezeichnen eine Seite mit minimalem Restplatz
als (100 %-tig) gef\o'u"'llt.
Der F\o'u"'llfaktor einer Seite entspricht dem
durch Tupel belegten Platz
im Verh\o'a"'ltnis zum Gesamtplatz.
.NH 4
.ft B
Schl\o'u"'sselbegriff von \*(yy
.ft R
.LP
In der Relationentheorie bezeichnet
man als Schl\o'u"'ssel einer Relation
eine derartige Dom\o'a"'ne (oder Gruppe von Dom\o'a"'nen),
deren Attribute allein das Tupel charakterisieren.
Beliebige zwei Tupel einer Relation unterscheiden sich also
mindestens in ihren Schl\o'u"'sseln.
.LP
Wenn in der \*(yy\-Dokumentation von Schl\o'u"'sseln
gesprochen wird, ist ein anderer, schw\o'a"'cherer Begriff
gemeint.
Bei \*(yy\ kann eine Dom\o'a"'ne
(oder eine Gruppe von in ihrer Reihenfolge
ge\%kennzeichneter Dom\o'a"'nen)
f\o'u"'r die Sortierung oder Zugriffsunterst\o'u"'tzung
herangezogen werden.
F\o'u"'r diese Dom\o'a"'ne(n) wird dann vom Schl\o'u"'ssel
der Relation gesprochen.
\*(yy\ unterstellt f\o'u"'r den Schl\o'u"'ssel nicht
unbedingt die o.g. unifizierende Eigenschaft,
dass sich zwei Tupel mindestens in ihren Schl\o'u"'sseln
unterscheiden m\o'u"'ssen.
.LP
F\o'u"'r \*(yy\ sind zwei Tupel genau dann gleich,
wenn sie in allen paarigen Attributen
\o'u"'bereinstimmen. An den Stellen,
wo \*(yy\ doppelte Tupel ausschliesst, wird nicht
nur auf Unterschiede in den Schl\o'u"'sselattributen,
sondern auf solche in allen paarigen
Attributen getestet.
.NH 4
.ft B
Seitenketten
.ft R
.LP
Wir wollen eine Gruppe von Seiten, die aus einer Hauptseite besteht,
an der ggf. weitere Seiten durch Verweisungen angekettet sind,
als Seitenkette bezeichnen.
Im Extrem besteht die Sei\%tenkette nur aus der Hauptseite.
Die Verweisungen erfolgen linear aus der Hauptseite
auf deren nachfolgende, aus dieser auf deren nachfolgende u.s.w.
In der Regel werden die der Hauptseite folgenden
Seiten als \o'U"'berlaufseiten bezeichnet.
Wir bezeichnen die in der Seitenkette enthaltenen Tupel als
Tupel\%kette der Seiten\%kette.
.DS L
Seitenkette ___________
| |
| Haupt |
| Seite |
| |
~~~~~~~~~~~
| ....................
___________ \o'U"'berlaufseiten
| |
| Folge |
| Seite |
| |
~~~~~~~~~~~
|
:
:
:
.DE
.LP
Gemeinsam bei allen Zugriffsmethoden ist:
.IP \ \ \ - 5
Die Suche eines Tupels in einer Seitenkette erfolgt
sequentiell.
.sp1
Sieht man von den hier nicht darzustellenden
Dekompositionsverfahren bei retrieve-Anweisungen
mit Aggregaten oder \o'u"'ber mehrere Relationen ab,
erfolgt die Anzeige aufgefundener Tupel
unmittelbar in der Reihenfolge der Tupelkette.
.sp1
.IP
Das Anf\o'u"'gen (append) eines Tupel in einer Seitenkette
erfolgt hinten an die Tupel der laufenden Seite;
wenn daf\o'u"'r kein Platz mehr ist,
wird die Seitenkette um eine neue Seite verl\o'a"'ngert.
.sp1
Dadurch geht die anfangs bestehende Reihenfolgeordnung
der Tupel in einer Seite und auch in der Seitenkette verloren.
.sp1
.IP
Beim Streichen (delete) eines Tupel wird der Platz des Tupel
freigegeben und die Seite komprimiert;
die Seitenkette wird nicht komprimiert.
.LP
Unterschiede zwischen den Zugriffsmethoden
bestehen darin:
.sp1
.IP \ \ \ - 5
bei der heap-Technik wird die gesamte Relation in einer
einzigen Seitenkette abgelegt, bei den Direktzugriffsmethoden
hash und isam besteht die Relation aus mehreren Seitenketten.
Die Unterschiede bei letzteren Techniken
bestehen in der Art der Zuordnung von
Schl\o'u"'sselwerten zu den verschiedenen Seitenketten
der Relation.
.sp1
.IP
Bei der heap-Technik werden doppelte Tupel in der Seiten\%kette
zugelassen, bei den Direktzugriffstechniken nicht.
.sp1
Daraus ergeben sich Unterschiede beim Anf\o'u"'gen neuer Tupel:
.br
Bei heap erfolgt die Einspeicherung
am Ende der Tupel\%kette,
bei hash und isam muss die gesamte Seiten\%kette
durchsucht werden, um doppelte Tupel auszuschliessen,
das Anf\o'u"'gen erfolgt
auf dem ersten ausreichenden freien Platz der Seitenkette.
Bei heap wird dadurch der durch delete entstandene
freie Platz nicht wieder ausgenutzt.
.sp1
Daraus ergeben sich auch Unterschiede beim Ersetzen (replace)
in komprimierten Relationen in solchen F\o'a"'llen,
wo das Ersetzen ggf. nicht inplace erfolgen kann.
Dann wird replace in delete und append aufgel\o'o"'st.
Beachten sie, dass jedes gefundene Tupel ersetzt wird,
replace also die Anzahl der Tupel einer Relation nicht \o'a"'ndert.
.NH 3
.ft B
Zugriffstechniken von \*(yy
.ft R
.NH 4
.ft B
Heap
.ft R
.LP
Eine als heap dargestellte Relation belegt
eine Seitenkette.
Bis auf die letzte Seite sind
bei Erzeugung der Relation
durch modify, copy from oder sukzessives append
alle Seiten
(100 %-tig) gef\o'u"'llt.
Die Tupel sind unsortiert.
Die Relation enth\o'a"'lt ggf. doppelte Tupel.
.LP
append f\o'u"'gt Tupel hinten an
(ggf. werden weitere Seiten angekettet !).
delete gibt Speicherplatz auf der jeweiligen Seite frei;
um die zu l\o'o"'schenden Tupel zu finden,
muss die gesamte Relation durchsucht werden.
Der freigegebene Platz kann durch append nicht wiederbenutzt werden,
da neue Tupel hinten angelegt werden.
retrieve durchsucht die gesamte Relation
und zeigt die sich qua\%lifizierenden
Tupel in der gefundenen, unsortierten Reihenfolge.
.LP
heap und cheap sind geeignete Zugriffstechniken,
um aus einer leeren Relation durch sukzessives Anf\o'u"'gen oder copy from
eine Relation aufzubauen.
Eine effektive Arbeit mit dieser Zugriffstechnik
ist aber nur bei kleinen Relationen denkbar.
.NH 4
.ft B
Heapsort
.ft R
.LP
heapsort ist keine Speichertechnik
sondern Zustand einer Relation
nach Ausf\o'u"'hrung eines entsprechenden modify-Statements;
die Relation ist in der Folge ein heap.
.LP
Bei der Ausf\o'u"'hrung eines modify to heapsort
wird die Relation nach den angesprochenen Dom\o'a"'nen
sortiert, werden doppelte Tupel gestrichen
und wird die Relation als heap abgelegt.
.LP
Zur Durchf\o'u"'hrung der Sortierung wird die Relation
gespreizt, falls sie komprimiert gespeichert war.
Es werden Sortierarbeitspl\o'a"'tze
als Files im SYS-directory angelegt.
.NH 4
.ft B
Hash
.tf R
.LP
F\o'u"'r eine als hash dargestellte Relation besteht ein
Direktzugriff auf ein Tupel,
wenn der Wert seines(r) Schl\o'u"'sselattribute(s)
vollst\o'a"'ndig angegeben wird.
Dieser Zugriff wird wie folgt vollzogen:
.LP
Durch eine hash-Funktion wird aus dem Schl\o'u"'sselattribut
die Adresse (der hash-Code) einer Hauptseite
berechnet.
Die hash Funktion berechnet also nach einem besonderen
Verfahren aus einem irgendwie strukturiertem Schl\o'u"'ssel
eine Zahl, die in einem Intervall
.DS C
0 <= Hauptseite <= N-1
.DE
liegt.
N bezeichnen wir als Spreizungsbreite der hash-Funktion.
Diese dadurch jeweils errechnete Hauptseite ist Anfangsseite
einer Seitenkette, die alle die Tupel der Relation enth\o'a"'lt,
deren Schl\o'u"'ssel den gleichen hash-Code haben.
In diesen Seitenketten werden keine doppelten Tupel zugelassen.
Die Relation kann insgesamt als unsortiert aufgefasst werden,
da die hash-Funktion keinen "nat\o'u"'rlichen" Wert
aus dem Schl\o'u"'ssel bildet.
.DS I
0
1
hash(Schl\o'u"'sselwert) = :
:
N-1
0 1 ......... N-1
________ ________ ________
| | | | | |
|Seiten| |Seiten| ......... |Seiten|
|kette | |kette | |kette |
| | | | | |
~~~~~~~~ ~~~~~~~~ ~~~~~~~~
.DE
.LP
Beim modify einer Relation zu hash
kann die Spreizungsbreite
der hash-Funktion durch die geforderte Anzahl von
Hauptseiten
(minpages/maxpages als minimale/maximale Anzahl)
beeinflusst werden.
Die Ausf\o'u"'hrung des modify erfolgt durch sukzessives insert
in eine neue Relation.
Die alte Relation wird aus Sicherheitsgr\o'u"'nden erst
freigegeben, wenn die neue erzeugt ist.
Beim create einer leeren Relation
kann man mit
modify
eine gew\o'u"'nschte Spreizungsbreite einstellen.
.LP
hash und chash sind geeignete Zugriffstechniken,
um aus einer leeren Relation durch sukzessives Anf\o'u"'gen
oder durch copy from eine Relation aufzubauen.
.LP
\*(yy\ unterst\o'u"'tzt nur eine hash-Funktion.
Es kann nicht garantiert werden,
dass die durch die Spreizungsbreite definierte Anzahl
von Seitenketten schon bei Erzeugung der Relation jeweils
mindestens ein Tupel und maximal nicht mehr als auf der Hauptseite
unterbringbar enthalten.
Allerdings wird f\o'u"'r jede Seitenkette mindestens
eine Hauptseite reserviert.
.LP
Die Suche in einer hash-Relation f\o'u"'r einen einzelnen Schl\o'u"'sselwert
f\o'u"'hrt \o'u"'ber dessen hash-Code
auf die Hauptseite, wo sequentiell weiter gesucht wird.
Die Suche nach einem Schl\o'u"'sselintervall zwingt zum Durchsuchen
der gesamten Relation.
Deshalb ist die hash-Technik ungeeignet,
wenn h\o'a"'ufig Suchpfade \o'u"'ber
Schl\o'u"'sselintervalle benutzt werden m\o'u"'ssen.
.LP
Das \o'A"'ndern in einer Relation erfolgt einschliesslich
der Suche und dem Ausschluss der Anlage doppelter Tupel.
Beim Erg\o'a"'nzen neuer Tupel wird die betroffene Seitenkette
ggf. durch \o'U"'berlaufseiten erg\o'a"'nzt, die an die
vorherigen Seiten der Seitenkette angekettet werden.
.NH 4
.ft B
Isam
.ft R
.LP
F\o'u"'r eine als isam dargestellte Relation
besteht ein Direktzugriff auf ein Tupel,
wenn der Wert seines(r) Schl\o'u"'sselattribute(s)
angegeben wird und besteht dar\o'u"'ber hinaus die M\o'o"'glichkeit,
Schl\o'u"'sselintervalle in einer ann\o'a"'hernden
Sortierung abzugreifen.
.LP
F\o'u"'r isam ist ein aus mehreren Komponenten
bestehender Schl\o'u"'ssel soweit definiert und ggf.
f\o'u"'r einen direkten Zugriff nutzbar,
wie seine ersten Komponenten l\o'u"'ckenlos
definiert sind.
.LP
Der Zugriff wird wie folgt organisiert:
.LP
Durch einen Adress-B*-Baum wird aus dem Schl\o'u"'sselattribut
die Adresse einer Hauptseite berechnet.
.LP
Ein B*-Adressbaum enth\o'a"'lt in jeder Baumebene
eine Folge von Seiten. Eine derartige Folge von Seiten
enth\o'a"'lt aufsteigend geordnete Schl\o'u"'ssel
von Seiten der darunter liegenden Baum\%ebene, also der
Nachfolgeebene.
Aus der Position des Schl\o'u"'ssels kann die betreffende Seite
der Nachfolgeebene bestimmt werden.
Diese enth\o'a"'lt ab dem sie definierenden Anfangsschl\o'u"'ssel
alle, die kleiner als der Anfangsschl\o'u"'ssel
ihrer, in gleicher Baumebene liegenden, Nachbarseite sind.
Der B*-Baum wird nach unten durch Hauptseiten
von Seitenketten abgeschlossen,
die zu den Schl\o'u"'sseln auch alle weiteren Attribute
als vollst\o'a"'ndige Tupel enthalten.
Der B*-Baum erh\o'a"'lt nach oben soviele Ebenen, bis die
Wurzelebene ganz auf einer Seite darstellbar ist.
.LP
Nehmen wir als Beispiel Schl\o'u"'ssel von ganzen Zahlen an und nehmen wir weiter an, dass auf
einer Seite der Seitenkette der Relation 5 Tupel unterbringbar w\o'a"'ren,
auf einer Seite des B*-Baumes aber 25 Adressen.
Dann w\o'a"'re folgender B*-Baum mit zwei Baumebenen denkbar:
.DS L
______________________________
| 5 130 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
________________________ ________________________
| 5 10 .... 125| |130 135 .... 255|
~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~
_____ _____ _____ _____ _____ _____ _____
| | | | | | | | | | | | | |
| 0 | | 5 | | 10| |125| |130| |135| |255|
| : | | : | | : | ..... | : | | : | | : | ..... | : |
| : | | : | | : | | : | | : | | : | | : |
| 4 | | 9 | | 14| |129| |134| |139| | : |
| | | | | | | | | | | | | |
~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~ ~~~~~
.DE
Die Genauigkeit des B*-Baumes w\o'u"'rde gew\o'a"'hrleisten,
dass im Schl\o'u"'sselintervall 0 ... 254
maximal 5 Tupel sequentiell gesucht werden m\o'u"'ssten,
dass in diesem Intervall keine \o'U"'berlaufseiten auftreten
und dass bei der Ausgabe Sortierabweichungen
nur in 5-er Schritten auftreten k\o'o"'nnten:
.br
z.B.
.DS I 12
9, 11, 13, 12, 14, 10, 17
aber nie 9 nach 10, 11, 12, 13, 14
oder nie 15 vor 10, 11, 12, 13, 14
.DE
Allerdings w\o'u"'rden alle Tupel mit Schl\o'u"'sselwerten ab 255
in die letzte Seitenkette eingeordnet werden.
.LP
Beenden wir hiermit das Beispiel.
.LP
Der B*-Baum ist Bestandteil der Relation.
.sp1
.ti +5
.ne 8
(seine L\o'a"'nge ist berechenbar:
.IP \ \ \ \ \ - 8
Tupell\o'a"'nge der Adresse:
.br
gespreizter Schl\o'u"'sselcode
.IP
jede Baumebene ganz in Seiten)
.LP
Die durch den B*-Baum ermittelten Hauptseiten
sind Anfangsseiten von Seitenketten,
die unsortiert alle Tupel enthalten und deren Schl\o'u"'ssel den
gleichen Baumpfad nehmen.
In diesen Seitenketten werden keine doppelten Tupel zugelassen.
Die B*-Baum-Struktur gew\o'a"'hrleistet f\o'u"'r gewisse
Schl\o'u"'sselintervalle
eine Sortierung untereinander.
.LP
Der B*-Baum wird bei der Erzeugung der Relation
angelegt und bleibt \o'u"'ber deren gesamte Lebensdauer fest.
Es ist unsinnig, eine leere Relation
als isam zu gr\o'u"'nden, der B*-Baum w\o'a"'re entartet,
man w\o'u"'rde eine einzige Seitenkette erzeugen,
bei dem bei jedem Einf\o'u"'gen eines neuen Tupel
eine Duplikatkontrolle \o'u"'ber alle bereits
vorhandenen Tupel erfolgen w\o'u"'rde.
.LP
Bei der Erzeugung der isam Relation durch modify
kann man die Genauigkeit des B*-Baumes
durch den F\o'u"'llfaktor der Hauptseiten
bestimmen.
Die alte Relation wird zun\o'a"'chst in eine Speicherungsform analog
heapsort \o'u"'berf\o'u"'hrt, diese wird danach, entsprechend dem
F\o'u"'llfaktor, gespreizt
und \o'u"'ber den so entstandenen Hauptseiten
wird der B*-Baum aufgebaut.
.LP
Die Suche in einer isam Relation kann f\o'u"'r die Angabe
von einzelnen Schl\o'u"'sselwerten, als auch f\o'u"'r
Intervalle von ihnen unterst\o'u"'tzt werden.
Das Anf\o'u"'gen erfolgt zun\o'a"'chst in den
Hauptseiten - soweit der F\o'u"'llfaktor des
erzeugenden modify vorausschauend gen\o'u"'genden Restplatz
definiert - danach werden der jeweiligen Seitenkette
\o'U"'berlaufseiten angef\o'u"'gt.
Das \o'A"'ndern in der Relation erfolgt einschliesslich
der Suche und dem Ausschluss der Anlage doppelter Tupel.
.NH 3
.ft B
Die Gestaltung des Datenbankfilesystems
.br
f\o'u"'r \*(yy
.ft R
.NH 4
.ft B
Einordnung einer Datenbank
.ft R
.LP
\*(yy\ wird installationsabh\o'a"'ngig
unter einem Anfangspfadnamen
.DS C
Pathname
.DE
installiert. Zum Beispiel ist
.DS C
Pathname = /mnt/ing_db
.DE
eingerichtet.
.LP
Unter diesem Pathname liegen eine Reihe hier nicht behandelter
Files und directories.
Die Datenbanken sind unter
.DS C
Pathname/data/base
.DE
eingerichtet, jede Datenbank erh\o'a"'lt ein directory ihres Namens:
.DS C
Pathname/data/base/dbname
.DE
In jedem directory dbname liegen
.sp1
.IP \ \ \ - 5
dbname/admin
.br
das s.g. admin-File mit allgemeinen Datenbankinformationen,
.sp1
.IP
die Systemkataloge
(die Relationen relation, references, attributes, integrity, protect, indexes),
die Relationen (Relationen schlechthin, Indizes)
.LP
Durch diese Struktur sind insbesondere
.DS B
base oder
dbname oder
SYS
.DE
mountbar.
.LP
Bei Erzeugung einer Datenbank mittels creatdb
wird das directory dbname
angelegt und werden die Systemkataloge eingerichtet.
.NH 4
.ft B
Bewertung des Relationennamens
.ft R
.LP
\*(yy\ speichert alle Daten einer Relation in einem \*(xx\-File
unter dem directory dbname.
Der File-Name wird aus dem vom Anwender
bei create oder retrieve into angegebenem Relationennamen
gebildet.
Dazu wird der Relationenname
.IP \ \ \ - 5
ggf. durch Leerzeichen (<blank>) auf 12 Bytes
verl\o'a"'ngert;
.br
dabei wird das erste in 2. bis 11. Position
gefundene "_" (<underscore>) durch "/" (<slash>)
ersetzt;
.IP
den 12 Bytes werden 2 Bytes als Code des
arbeitenden Nutzers (s. auch
-u-Flag bei quel(unix) im Referenz-Manual)
angef\o'u"'gt.
.LP
Dadurch wird es m\o'o"'glich, dass
.IP -
verschiedene Nutzer private Relationen gleichen
Namens in der gleichen Datenbank anlegen k\o'o"'nnen;
.IP -
ein Nutzer durch sinnvolle Verwendung des <underscore>
im Relationennamen die Verteilung der Relationen
auf das Wurzel-directory dbname oder in sub-directories
von dbname steuern kann.