P8000/WEGA/contrib/ingres/dbs/ing_src/teil2/dab

3108 lines
58 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

.ds RH \f3Datenbank\f1
.ds CH - % -
.ds LH Anwendung
.bp
.NH 2
.ft B
Arbeit mit Datenbanken *
.ft R
.LP
.sp 10
.NH 3
.ft B
Vorbemerkung *
.ft R
.LP
In diesem Abschnitt wird beschrieben,
wie die Relationen der Datenbank erzeugt,
strukturiert und verwaltet werden.
Es wird davon ausgegangen,
dass der Leser etwas vertraut ist und die Anfragesprache
QUEL von \*(yy\ versteht.
.sp 1
Um eine neue Datenbank zu gr\o'u"'nden,
m\o'u"'ssen sie ein g\o'u"'ltiger (eingetragener)
\*(yy\-Nutzer sein und die
.ft B
creatdb
.ft R
\-Erlaubnis haben.
Diese Erlaubnis wird vom \*(yy\-Sy\%stem\%ad\%mi\%ni\%stra\%tor verliehen.
Wenn sie beide Bedingungen erf\o'u"'llen,
k\o'o"'nnen sie eine Datenbank unter
Verwendung des \*(xx\-Shell-Kommandos
.sp 1
.ft B
% creatdb meindb
.ft R
.sp 1
gr\o'u"'nden, wobei
.ft B
meindb
.ft R
der Name der Datenbank ist.
Sie werden Datenbankadministrator (DBA) f\o'u"'r
"meindb".
Als DBA haben sie spezielle Berechtigungen.
.sp
.IP 1.
Alle von ihnen erzeugten Relationen
k\o'o"'nnen von allen anderen,
.ft B
meindb
.ft R
verwendenden,
Nutzern benutzt werden.
Erzeugt aber dagegen ein beliebiger Nutzer eine Relation,
so ist sie strikt privat und auf sie kann weder vom DBA
noch von einem anderen Nutzer zugegriffen werden.
.RE
.sp
.IP 2.
Sie k\o'o"'nnen das
.ft B
-u
.ft R
\-Flag in
.ft B
quel
.ft R
und
.ft B
printr
.ft R
verwenden.
Das bef\o'a"'higt sie, \*(yy\ auf
.ft B
meindb
.ft R
als ein anderer Nutzer laufen zu lassen.
Schlagen sie im \*(yy\-Referenz-
Manual unter den Kapiteln
.ft B
quel(unix)
.ft R
und
.ft B
users(files)
.ft R
wegen detaillierten Angaben nach.
.RE
.sp
.IP 3.
Sie k\o'o"'nnen mit
.ft B
sysmod
.ft R
,
.ft B
restore
.ft R
,
.ft B
creatdb
.ft R
,
.ft B
destroydb
.ft R
und
.ft B
purge
.ft R
auf
.ft B
meindb
.ft R
arbeiten.
.RE
.sp
.IP 4.
Eine Datenbank, die ohne Angabe von Flags gegr\o'u"'ndet
wurde, gestattet mehrere mitwirkende Nutzer.
Wenn jeweils nur ein Nutzer die Datenbank zu
bestimmter Zeit verwenden m\o'o"'chte,
kann der Datenbankadministrator die Gleichzeitigkeitskontrolle
ausschalten.
Schlagen sie unter
.ft B
creatdb(unix)
.ft R
im \*(yy\-
Referenz-Manual nach.
.RE
.sp 1
Wenn eine Datenbank gegr\o'u"'ndet ist, sollten sie
sofort
.sp 1
.ft B
% sysmod meindb
.ft R
.sp 1
geben. Dieses Kommando konvertiert
die Systemrelationen in die g\o'u"'nstigste
Struktur zur Verwendung in \*(yy\.
.ft B
sysmod
.ft R
wird sp\o'a"'ter ausf\o'u"'hrlich erkl\o'a"'rt.
.sp 1
Als DBA oder als ein Nutzer k\o'o"'nnen sie neue Relationen in
jeder Datenbank erzeugen, zu der
sie Zugriffsrecht haben.
Die vorliegenden Ausf\o'u"'hrungen beschreiben, wie das gemacht werden muss.
.NH 3
.ft B
Erzeugung neuer Relationen mit QUEL
.ft R
.LP
Es gibt zwei Wege um neue Relationen mit QUEL zu erzeugen.
.sp 1
.IP
create
.br
retrieve into
.RE
.sp 1
.ft B
retrieve into
.ft R
wird verwendet, um eine neue Relation aus einer oder
mehreren existierenden Relationen zu formieren.
.ft B
create
.ft R
wird verwendet, um
eine neue Relation ohne Tupel (leer) zu erzeugen.
.sp 1
Beispiel 1:
.sp 1
.DS
range of t is teile
range of l is lieferung
retrieve into neuliefrg(
nummer = l.lnum,
t.tname,
l.liefdat)
where l.tnum = t.tnum
.DE
.sp 1
Beispiel 2:
.sp 1
.DS
create neuliefrg(
nummer = i2,
tname = c20,
liefdat = c8)
.DE
.sp 1
Im Beispiel 1 erzeugt QUEL eine neue Relation, genannt
"neuliefrg". Das Format der Dom\o'a"'nen wird
berechnet.
Die Query wird bearbeitet und "neuliefrg"
modifiziert zu "cheapsort".
(Dies wird ausf\o'u"'hrlicher im Abschitt 2.2.4. erkl\o'a"'rt.)
.sp 1
Im Beispiel 2 wird "neuliefrg"
erzeugt und der Name sowie
das Format f\o'u"'r jede Dom\o'a"'ne angegeben.
Die zugelassenen Formattypen sind:
.sp 1
.DS I
i1 1 Byte Integer
i2 2 " "
i4 4 " "
f4 4 Byte Gleitkommazahl
f8 8 " " " "
c1,c2,..,c255 1,2,..,255 Byte Zeichenkette
.DE
.sp 1
Im Beispiel 2 betr\o'a"'gt die L\o'a"'nge eines einzelnen Tupel
30 Byte
(2 + 20 + 8). Die
Relation hat drei Dom\o'a"'nen.
Es ist klar, dass \*(yy\
Grenzen hat.
Eine Relation kann
installationsabh\o'a"'ngig 49 bzw. 128 Dom\o'a"'nen und eine Tupell\o'a"'nge
von \o'u"'ber 498 bzw. 1010 Byte haben.
.sp 1
\*(xx\ stellt den Speicherplatz auf der Platte in
Bl\o'o"'cken von 512 Byte, 1KByte bzw. 4KByte bereit.
Datens\o'a"'tze werden in \*(yy\ in Seiten (pages)
abgelegt, deren Gr\o'o"'ssen beim Anlegen einer
Datenbank eingestellt werden.
Die maximale Seitengr\o'o"'sse ist generierungsabh\o'a"'ngig.
.br
\*(yy\ teilt ein Tupel nicht
\o'u"'ber zwei Seiten,
so kann es vorkommen,
dass Speicherplatz vergeudet wird.
In einer Seite werden f\o'u"'r den
.ft B
overhead
.ft R
12 Bytes zuz\o'u"'glich
je 2 Byte pro Tupel f\o'u"'r Verwaltungsaufgaben genutzt.
Die Berechnungsvorschriften sind:
.sp 1
.DS L
Anzahl der Tupel pro Seite =
(Seitengr\o'o"'sse-12)/(Tupell\o'a"'nge + 2)
.sp 1
Verschwendeter (oder verschenkter) Speicherplatz =
(Seitengr\o'o"'sse-12) - (Anzahl der Tupel pro Seite) *
* (Tupell\o'a"'nge + 2)
.sp 1
.DE
F\o'u"'r unser Beispiel und 512-Byte-Seitengr\o'o"'sse ergibt das
.sp 1
.IP
15 = 500 / (30 + 2)
.br
.sp 1
20 = 500 - 15 * (30 + 2)
.RE
.sp 1
15 Tupel pro Seite und 20 Bytes
unbelegter Platz.
Diese Berechnung gilt nicht f\o'u"'r
komprimierte Relationen.
Wir werden auf dieses Problem im
Weiteren zur\o'u"'ckkommen, wenn Tupelkompression diskutiert wird.
.sp 1
Wenn sie einen Dom\o'a"'nenname oder ein Format vergessen haben,
benutzen sie das "help"-Kommando.
Geben sie auf das Beispiel bezogen das QUEL-
Kommando
.sp 1
.IP
help neuliefrg
.RE
.sp 1
wird folgendes gedruckt:
.DS
Relation: neuliefrg
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Owner: bob
Tuple width: 30
Saved until: Thu Nov 10 08:35:06 1988
Number of tuples: 0
Storage structure: heap
Relation type: user relation
attribute name type length keyno.
nummer i 2
tname c 20
liefdat c 8
.DE
Merken sie sich, dass jede Relation ein Verfallsdatum
hat.
Es wird ausgehend vom Erzeugungsdatum der Relation
auf eine Woche festgesetzt.
Das
.ft B
save
.ft R
\-Kommando
kann verwendet werden, um diesen Zeitraum zu verl\o'a"'ngern.
Beachten sie dazu
.ft B
save(quel)
.ft R
und
.ft B
purge(unix)
.ft R
im
\*(yy\-Referenz- Manual.
.NH 3
.ft B
Das Kopieren von Daten aus und in eine
.ft R
.br
.ft B
Datenbank
.ft R
.LP
.NH 4
.ft B
Allgemeine M\o'o"'glichkeiten
.ft R
.LP
Wenn eine Relation gegr\o'u"'ndet wurde, gibt es folgende M\o'o"'glichkeiten,
neue Daten einzuf\o'u"'gen:
.sp
.IP
append-Kommando
.br
copy-Kommando
.RE
.sp
.ft B
append
.ft R
wird zum Einf\o'u"'gen eines einzelnen Tupel zu irgend\%einem
Zeitpunkt oder zum F\o'u"'llen einer
Relation aus anderen Relationen verwendet.
.sp
.ft B
copy
.ft R
wird zum Kopieren von Daten aus einem \*(xx\-File in eine
Relation benutzt.
Es ist anzuwenden, um Daten von einem anderen Programm oder von einem
anderen System zu kopieren.
Es ist auch gebr\o'a"'uchlich, um gr\o'o"'ssere Datenmengen
zu kopieren.
.sp
Wir wollen nun eine einfache Relation erzeugen
und Daten dort einbringen.
.sp
Beispiel:
.sp
.DS
create abgabe (name = c10, wert = f4, ext = i2)
.DE
Jetzt sollen zwei Personen eingegeben werden.
Die einfachste M\o'o"'glichkeit ist nat\o'u"'rlich, diese Eingabe unter
Verwendung des QUEL-Kommandos
.ft B
append
.ft R
zu vollziehen.
.sp
.DS
append to abgabe (name="frank",wert = 5,ext = 204)
append to abgabe (name="harry",ext = 209,wert = 4.50)
.DE
.sp
\*(yy\ erkennt die Dom\o'a"'nen
an ihren Namen, unabh\o'a"'ngig von ihrer
aufgelisteten Reihenfolge.
Die Relation
.ft B
abgabe
.ft R
sieht jetzt so aus:
.DS
abgabe relation
|name |wert |ext |
|----------------------------|
|frank |5.000 |204 |
|harry |4.500 |209 |
|----------------------------|
.DE
.sp
Wir haben zwei Personen in die
.ft B
abgabe
.ft R
\-Relation eingegeben.
Doch was ist, wenn wir weitere f\o'u"'nfzig einzugeben h\o'a"'tten.
Die Verwendung des "append"-Kommandos ist aufgrund der umfangreichen
Angaben f\o'u"'r jedes Tupel nicht geeignet.
Das
.ft B
copy
.ft R
\-Kommando entspricht besser unseren Anforderungen.
.sp
.ft B
copy
.ft R
kann Daten von einem regul\o'a"'ren
\*(xx\-File in verschiedenen Formaten \o'u"'bernehmen
und sie in die Relation einf\o'u"'gen.
Um das "copy"-Kommando zu verwenden, ist vorher
ein \*(xx\-File (\o'u"'blicherweise mit "ed") zu erzeugen, das die
Daten enth\o'a"'lt.
.sp
Als Beispiel wollen wir f\o'u"'nf neue Namen in das File
unter Verwendung des Editor's eintragen.
.LP
.DS L
% ed
a
bill,3.50,302
sam,10.00,410
susan,,100
sally,.5,305
george,4.00,302
w newdom
68
q
%
.DE
Das Format des obenstehenden Files ist
ein Name gefolgt von einem Komma, gefolgt von
einem Wert (wert), dann ein Komma, dann die Erweiterung (extension)
und schliesslich ein Newline.
Es ist zulaessig, Werte nicht anzugeben, wie zum Beispiel "wert"
bei "susan".
Solche Leerwerte werden bei
numerischen Dom\o'a"'nen zu
Null (0) und bei Zeichenketten auf blanks (Leerzeichen) gesetzt.
.LP
Um zu kopieren, starten wir \*(yy\ und geben das "copy"-Kommando.
.LP
.DS L
copy abgabe (name = c0, wert = c0, ext = c0)
from "/mnt/bob/newdom"
.DE
.LP
Das "copy"-Kommando arbeitet folgendermassen:
.LP
.DS L
copy relname (Liste, was zu kopieren ist) from "voller pathname"
.DE
.LP
Obwohl "wert" und "ext" in der Relation
als f4 (Gleitkomma) und i2 (Integer) gespeichert sind,
haben wir sie im
\*(xx\-File aber als Zeichenketten eingegeben.
Zur Spezifizierung des Formats der Dom\o'a"'ne akzeptiert
.ft B
copy:
.ft R
.IP
domain = format
.LP
wobei
.ft B
domain
.ft R
der Dom\o'a"'nenname und
.ft B
format
.ft R
im \*(xx\-File einer der folgenden Werte ist:
.LP
.DS L
i1, i2, i4 (Integer der L\o'a"'nge 1, 2, oder 4)
f4, f8 (Gleitkommazahl der L\o'a"'nge 4
oder 8)
c1, c2, c3,...c255 (Zeichenkette mit fester L\o'a"'nge)
c0 (Zeichenkette mit variabler L\o'a"'nge,
begrenzt durch Komma, Tabulator oder
Newline)
.DE
Im Beispiel verwenden wir:
.IP
name = c0, wert = c0, extension = c0
.LP
Das bedeutet, dass jede Dom\o'a"'ne
im \*(xx\-File als Zeichen\%kette mit
variabler L\o'a"'nge gespeichert war.
.ft B
copy
.ft R
verwendet das erste Komma-,
Tabulator- oder Newline-Zeichen als Ende der Zeichenkette.
Das ist ungef\o'a"'hr die gebr\o'a"'uchlichste Nutzung von
.ft B
copy
.ft R
, wenn neue Daten erstmalig in eine
Relation eingebracht werden.
.LP
.ft B
copy
.ft R
kann auch benutzt werden, um Daten aus einer Relation
in ein \*(xx\-File zu kopieren.
Zum Beispiel:
.LP
.DS L
copy abgabe (name = c10, wert = c10, ext = c5)
into "/mnt/bob/data"
.DE
.LP
Folgendes ereignet sich:
.IP 1.
Wenn das File /mnt/bob/data bereits existiert, wird
es zerst\o'o"'rt.
.IP 2.
Das File wird im Modus 600
(nur read/write-Erlaubnis f\o'u"'r den Nutzer) erzeugt.
.IP 3.
"name" wird als ein 10-Zeichenfeld kopiert,
unmittelbar gefolgt von "wert",
unmittelbar gefolgt von "ext".
"wert" wird konvertiert in eine Zeichenkette
der L\o'a"'nge 10.
"ext" wird konvertiert in eine Zeichenkette
der L\o'a"'nge 5.
.LP
Das File
.ft B
/mnt/bob/data
.ft R
wird eine Folge von Zeichen,
die folgendermassen aussieht:
.DS L
frank``````````5.000``204harry``````````4.500 209bill
```````````3.500``302sam```````````10.000 410susan```
```````0.000``100sally``````````0.500``305george``````
```4.000``302
.DE
.LP
Dabei steht "`" f\o'u"'r <blank>.
Die Ausgabe wurde zur Darstellung entsprechend
des vorliegenden Papierformates
in vier Zeilen geteilt.
In Wirklichkeit ist das File
eine einzige Zeile.
Ein anderes Beispiel:
.sp
.DS
copy (name = c0, colon = d1, ext = c0, comma = d1,
wert = c0, nl = d1) into "/mnt/bob/data"
.DE
.sp
In diesem Beispiel wird
.ft B
c0
.ft R
interpretiert als "nutze
das festgelegte Zeichenketten-Format".
F\o'u"'r Zeichenketten-Dom\o'a"'nen ist das die
L\o'a"'nge der Dom\o'a"'ne.
Numerische Dom\o'a"'nen werden konvertiert in Zeichenketten
entsprechend dem \*(yy\-Standardformat
(siehe quel(unix)).
.sp
Die Statements:
.IP
colon = d1
.br
comma = d1
.br
nl = d1
.LP
werden benutzt um einen Doppelpunkt,
ein Komma oder ein Newline in das File einzuf\o'u"'gen.
Das Format
.ft B
d1
.ft R
wird als Pseudo-Zeichen (dummy) interpretiert.
W\o'a"'hrend des Kopierens in ein \*(xx\-File
kann eine ausgew\o'a"'hlte Menge von Zeichen in das File unter
Verwendung der
.ft B
dummy domain
.ft R
\-Spezifikation eingef\o'u"'gt werden.
So w\o'u"'rde das File "/mnt/bob/data" aussehen:
.DS L
frank : 204, 5.000
harry : 209, 4.500
bill : 302, 3.500
sam : 410, 10.000
susan : 100, 0.000
sally : 305, 0.500
george : 302, 4.000
.DE
.LP
Wenn sie ein File mit der wirklichen Bin\o'a"'rdarstellung der
Zahlen w\o'u"'nschen, ist zu verwenden:
.IP
copy (name = c10, wert = f4, ext = i2) into "..."
.LP
Dies w\o'u"'rde ein File mit einer exakten
Kopie von jedem Tupel,
eins nach dem anderen, erzeugen.
Es ist h\o'a"'ufig w\o'u"'nschenswert und das wird hier bezweckt, f\o'u"'r tempor\o'a"'re Backups die Garantie
zu haben, dass die Gleitkomma-Dom\o'a"'nen
exakt abgebildet sind.
.NH 4
.ft B
Typische Fehler
.ft R
.LP
Es gibt 17 verschiedene Fehler
die bei "copy" auftreten k\o'o"'nnen.
Wir wollen einige der h\o'a"'ufigsten
durchgehen.
.LP
Angenommen sie haben ein File mit
.sp 1
bill,3.5,302
.br
sam,10,410,
.br
susan,3,100
.sp 1
und arbeiten das "copy"-Kommando
.LP
.DS
copy abgabe (name = c0, wert = c0, ext = c0)
from "/mnt/bob/data"
.DE
.sp 1
ab, dann erhalten sie die Fehlermitteilung
.sp 1
.DS L
5809: COPY: Bad input String for Domain wert.
Input was "susan".There were 2 tuples sucessfully
copied from /mnt/bob/data into abgabe.
.DE
.LP
Folgendes hat sich ereignet:
.IP
Zeile 2 hat ein extra Komma, die ersten beiden
Tupel wurden richtig kopiert,
das n\o'a"'chste Tupel ergibt sich dann zu
name = "" (blank), wert =
"susan", and ext = "3".
Aber "susan" ist keine erlaubte Gleitkommazahl,
ein Fehler wird generiert und
der Prozess wird nach zwei Tupel gestoppt.
.LP
Wenn sie versuchen ein solches File
wie
.sp 1
nancy,5.0,35000
.sp 1
zu kopieren erhalten sie die Fehlermitteilung
.DS L
5809: COPY: Bad input String for Domain ext.
Input was "35000". There were 0 Tuples successfully
copied from /mnt/bob/data into abgabe.
.DE
.LP
Hier gilt "ext" als eine i2 (Integer)-Dom\o'a"'ne,
Sie kann den Wert 32767 nicht \o'u"'berschreiten.
.LP
Es gibt weitere "numerische" Fehlermitteilungen,
die meisten sind selbsterkl\o'a"'rend.
.LP
Hinzuzuf\o'u"'gen sind drei, nicht verh\o'a"'ngnisvolle Warnungen,
die bei
.ft B
copy from
.ft R
auftreten k\o'o"'nnen.
.LP
Wenn sie von einem File
in eine Relation der Art
.ft B
isam
.ft R
oder
.ft B
hash
.ft R
kopieren, wird die Anzahl
der doppelten Tupel mitgeteilt (, sofern welche enthalten sind).
Das kann bei
.ft B
heap
.ft R
nicht geschehen,
weil auf doppelte Tupel nicht gepr\o'u"'ft wird.
.LP
\*(yy\ ist nicht in der Lage
.ft B
control characters
.ft R
(solche wie
.ft B
bell
.ft R
etc.)
zu speichern.
Wenn
.ft B
copy
.ft R
ein
.ft B
control character
.ft R
liest, konvertiert es dieses in
.ft B
blank
.ft R
und teilt die Anzahl der Dom\o'a"'nen
mit, in denen diese Zeichen enthalten waren.
.LP
Wenn sie mit der c0
-Option kopieren, wird "copy" ihnen mitteilen,
wieviele Zeichen\%ketten l\o'a"'nger als ihre zugeh\o'o"'rigen Dom\o'a"'nen
waren und gek\o'u"'rzt werden.
Die Zeichenkette wird abgeschnitten.
.NH 4
.ft B
Spezielle M\o'o"'glichkeiten
.ft R
.LP
Es gibt einige spezielle Funktionen, die
.ft B
copy
.ft R
in der Handhabung etwas erleichtern.
.NH 5
.ft B
Physische Kopie (bulk copy)
.ft R
.LP
Wenn sie
.DS I
copy relname () from "file"
oder
copy relname () into "file"
.DE
geben, erweitert "copy" das Statement in folgender Bedeutung:
.IP
Kopiere jede Dom\o'a"'ne in ihrer genauen Reihenfolge entsprechend
ihres festgelegten Formats.
.LP
Wenn sie sagen w\o'u"'rden
.IP
copy abgabe () into "/mnt/bob/abgabe"
.LP
w\o'a"'re es dasselbe wie:
.DS I
copy abgabe (name = c10, wert = f4, ext = i2)
into "/mnt/bob/abgabe"
.DE
Dies verschafft ihnen einen bequemen Weg, um
ganze Relationen von und nach \*(yy\ zu kopieren,
bspw. aber auch von einer Datenbank in die andere.
.NH 5
.ft B
Pseudodom\o'a"'nen (Dummy Domains)
.ft R
.LP
Wenn sie Daten von einem anderen
Computer oder einem anderen Programm kopieren wollen,
kann es vorkommen, dass ein Teil
der Daten ignoriert werden soll.
Das k\o'o"'nnen sie unter Verwendung
der
.ft B
dummy domain
.ft R
\-Spezifikation
d0, d1, d2 ... d511 realisieren.
Zum Beispiel
.DS I
copy rel (dom1 = c5, dummy = d2, dom2 = i4,
dumb = d0) from "/mnt/me/data"
.DE
Die ersten f\o'u"'nf Zeichen
werden in dom1 abgelegt,
die n\o'a"'chsten zwei werden ignoriert.
Die n\o'a"'chsten vier Bytes geh\o'o"'ren zum Typ i4 (Integer)
und gehen zu dom2,
und die verbleibende begrenzte Zeichenkette
wird ignoriert.
Der Name der
.ft B
dummy
.ft R
\-Dom\o'a"'ne
wird \o'u"'berlesen,
die Dom\o'a"'ne muss nicht unbedingt
.ft B
dummy
.ft R
heissen, wie das bei
.ft B
dumb = d0
.ft R
der Fall ist.
.LP
Wie schon erw\o'a"'hnt,
k\o'o"'nnen "dummy"-Dom\o'a"'nen verwendet werden,
um bei einem "copy into" auf ein \*(xx\-File Spezialzeichen
("special characters") einzuf\o'u"'gen.
Die Liste der zugelassenen Dom\o'a"'nen enth\o'a"'lt:
.DS I
nl newline
tab tab character
sp space
nul a zero byte
null a zero byte
comma ,
dash -
colon :
lparen (
rparen )
.DE
.sp 1
.NH 5
.ft B
Abschneiden (Truncation)
.ft R
.LP
Es ist nicht ungew\o'o"'hnlich, dass nach einem aufgetretenen Fehler
nochmals gestartet werden muss.
Der einfachste Weg, das zu tun,
ist das L\o'o"'schen der alten Relation.
Es wird mit dem Kommando
.IP
modify relname to truncated
.LP
realisiert und hat den Effekt des L\o'o"'schens
aller Tupel in
.ft B
relname
.ft R
, bei gleichzeitiger Freigabe des belegten Plattenspeicherbereichs
und der Umwandlung von
.ft B
relname
.ft R
zur\o'u"'ck zu
.ft B
heap
.ft R
\&. Es ist das logische \o'A"'quivalent zum
.ft B
destroy
.ft R
gefolgt von
.ft B
create
.ft R
(aber mit etwas weniger Eingabearbeit).
.LP
Da in den verwendeten Files Formatfehler nicht
auszuschliessen sind, ist es
im Allgemeinen keine gute Idee
mit
.ft B
copy
.ft R
Daten in eine Relation mit bereits
gepr\o'u"'ften Daten zu transportieren.
Die g\o'u"'nstigste Verfahrensweise ist,
eine tempor\o'a"'re Relation mit den selben Dom\o'a"'nen
zu erzeugen,
wie sie die existierende Relation besitzt.
Ko\%pieren sie die Daten in die tempor\o'a"'re Relation
und dann h\o'a"'ngen ("append") sie diese an die echte Relation an.
Zum Beispiel:
.DS I
create tempdom(name=c10,wert=f4,ext=i2)
copy tempdom(name=c0,wert=c0,ext=c0)
from "/mnt/bob/data"
range of td is tempdom
append to abgabe(td.all)
.DE
.sp 1
.NH 5
.ft B
Spezielle Begrenzer (Specifing Delimitors)
.ft R
.LP
Manchmal ist es w\o'u"'nschenswert das Zeichen
zu spezifizieren,
welches die Zeichenfolge
bei "copy from file" begrenzen soll.
Das ist mit der Angabe
.IP
domain = c0delim
.LP
m\o'o"'glich, wobei
.ft B
delim
.ft R
ein g\o'u"'ltiger Begrenzer (delimitor)
aus der Liste der zugelassenen Namen oder ein
beliebiges Zeichen ist.
Diese Liste wurde weiter oben
unter
.ft B
dummy domains
.ft R
aufgef\o'u"'hrt.
Bei den Zeichen muss beachtet werden, dass der
beliebige Delimitor ein Zeichen sein muss, welches
der interaktive Terminal-Monitor annimmt und der Parser
nicht als Operator interpretiert.
(Diese Interpretationsart kann umgangen werden, indem
die Angabe
.ft B
c0delim
.ft R
als String gequotet wird. Das heisst, der
gew\o'u"'nschte Delimitor m\o'u"'sste in der Form "
.ft B
c0)
.ft R
"geschrieben werden.
Zum Beispiel:
.IP
copy abgabe (name = c0nl) from "/mnt/me/data"
.LP
kopiert "name" des Files in die Relation.
Nur ein Newline begrenzt die Namen richtig, weil
Kommas oder Tabulatoren eventuell als Teil eines
Namens auftreten k\o'o"'nnen.
.LP
Bei
.ft B
copy into file
.ft R
wird
.ft B
delim
.ft R
immer sofort in das File geschrieben,
so dass bei
.ft B
copy into
.ft R
die Spezifikation lautet:
.IP
copy abgabe (name = c0nl) into "/mnt/me/file"
.LP
Genauer gesagt, "name" wird unmittelbar gefolgt von Newline.
.NH 5
.ft B
Aufhebung der Begrenzer (Quoting)
.ft R
.LP
Soll in einem Wert einer Dom\o'a"'ne
der g\o'u"'ltige Begrenzer Verwendung finden,
so muss er kaschiert (aufgehoben) werden.
Dies geschieht durch das Voranstellen
eines backslash
.ft B
\e
.ft R
vor dem Begrenzer.
.br
So kann z.B. das Tupel
.IP
donald\e, mc, 6.0, 403
.LP
korrekt mittels
.DS I
copy abgabe (name = c0, wert = c0, ext = c0)
from "/mnt/bob/data"
.DE
kopiert werden, wobei "name" den Wert
"donald, mc", "wert" den Wert "6.0" neu
erh\o'a"'lt.
.NH 3
.ft B
Speicherstrukturen f\o'u"'r Relationen
.ft R
.LP
.NH 4
.ft B
Einf\o'u"'hrung
.ft R
.LP
Wenden wir uns nun den Problemen der Effizienz zu.
Haben sie erst einmal eine Relation erzeugt
und Ihre Daten unter
Verwendung von
.ft B
copy
.ft R
oder
.ft B
append
.ft R
eingef\o'u"'gt,
kann \*(yy\ jede beliebige Query (Kommando aus QUEL)
in der Relation ausf\o'u"'hren.
Es gibt mehrere M\o'o"'glichkeiten, zur
Erh\o'o"'hung der
Geschwindigkeit, mit der \*(yy\ die Query ausf\o'u"'hrt.
.LP
\*(yy\ kann eine Relation in drei verschiedenen
internen
Strukturen speichern.
Sie werden
.ft B
heap
.ft R
,
.ft B
isam
.ft R
und
.ft B
hash
.ft R
genannt.
Zuerst wollen wir jede Struktur genauer
beschreiben und sp\o'a"'ter unsere Betrachtung
ausdehnen.
.NH 4
.ft B
Heap
.ft R
.LP
Wird eine Relation erstmalig erzeugt, ist sie
vom Typ "heap".
Es gibt zwei wichtige Feststellungen zu
.ft B
heap:
.ft R
doppelte Tupel werden nicht gel\o'o"'scht
und die Lokalisierung der Tupel ist unbekannt.
Wenn sie die folgende Query ausf\o'u"'hren
.IP
range of a is abgabe
.br
retrieve (a.wert) where a.name = "bill"
.LP
muss \*(yy\ jedes Tupel lesen und pr\o'u"'fen, ob der
Name "bill" dort auftritt.
Bei kleinen Relationen ist das nicht schlimm,
aber bei sehr grossen Relationen kann das Minuten
(oder eben bei Computern mit kleinen
Hauptspeichern Stunden!) dauern.
.NH 4
.ft B
Hash
.ft R
.LP
Bei einer Relation, deren Struktur
.ft B
hash
.ft R
ist, kann ein schneller
Zugriff auf Tupel gew\o'a"'hrt werden,
wenn die Suche (Recherche) durch bestimmte
Dom\o'a"'nen gesteuert wird.
Diese Dom\o'a"'nen werden gew\o'o"'hnlich als
.ft B
keyed domains
.ft R
(Schl\o'u"'ssel bzw.
Schl\o'u"'sseldom\o'a"'nen) bezeichnet.
Weiterhin enthalten,
.ft B
hash
.ft R
\-Relationen
keine doppelten Tupel.
Nehmen wir beispielsweise an, dass die "abgabe"-Relation als
.ft B
hash
.ft R
auf
die Dom\o'a"'ne "name" gespeichert ist.
In der Query
.IP
retrieve (a.wert) where a.name = "bill"
.LP
wird \*(yy\ schnell herausbekommen,
wo sich das Tupel ann\o'a"'hernd auf der Platte
befindet.
Wenn die Relation nur einige wenige Tupel enth\o'a"'lt, k\o'o"'nnen sie
den Unterschied zwischen
.ft B
heap
.ft R
\-und
.ft B
hash
.ft R
\-Struktur nicht bemerken.
Aber wenn die Relation gr\o'o"'sser wird, ist
die Zugriffszeit von sp\o'u"'rbarer
Bedeutung.
.NH 4
.ft B
Isam
.ft R
.LP
Eine
.ft B
isam
.ft R
\-Struktur liegt dann vor, wenn die Relation nach
einer oder mehreren Dom\o'a"'nen sortiert ist
(auch
.ft B
keyed domains
.ft R
genannt).
Doppelte Tupel treten bei "isam"-Relationen nicht auf.
Wenn ein neues Tupel angef\o'u"'gt wird, wird es
"ann\o'a"'hernd" an der Stelle platziert, die der Sortierposition in der
Relation entspricht.
(Das "ann\o'a"'hernd" wird etwas sp\o'a"'ter erl\o'a"'utert.)
.LP
Angenommen "abgabe" hat die Struktur
.ft B
isam
.ft R
auf die Dom\o'a"'ne "name".
Die Ausf\o'u"'hrung der Query
.IP
retrieve (a.wert) where a.name = "bill"
.LP
wird \*(yy\ veranlassen, festzustellen, wo in der sortierten
Folge der Name "bill" steht und nur dieser
Teil der Relation wird gelesen.
.LP
Wenn die Relation ann\o'a"'hernd sortiert ist, ist
eine
.ft B
isam
.ft R
\-Struktur auch effizient zur
Ausf\o'u"'hrung der Query:
.IP
retrieve (a.wert) where a.name >= "b" and a.name < "g"
.LP
Diese Query zeigt alle Namen, die mit "b" bis "f" beginnen.
Es ist nicht n\o'o"'tig, die gesamte Relation zu
durchsuchen,
da sie eine
isam
\-Struktur \o'u"'ber "name" besitzt.
.NH 4
.ft B
Spezifizierung der Speicherstruktur
.ft R
.LP
Eine von einem Nutzer erzeugte Relation kann durch Anwendung
des
.ft B
modify
.ft R
\-Kommandos in eine der Speicherstrukturen konvertiert werden.
Zum Beispiel
.DS I
modify abgabe to hash on name
oder
modify abgabe to isam on name
oder eben
modify abgabe to heap
.DE
.sp 1
.NH 4
.ft B
Haupt-(primary) und
.br
\o'U"'berlauf-(overflow) Seiten
.ft R
.LP
An dieser Stelle ist es notwendig auf das
Konzept der Haupt- und \o'U"'berlauf-Seiten bei
.ft B
hash
.ft R
\-und
.ft B
isam
.ft R
\-Strukturen einzugehen.
Beide,
.ft B
hash
.ft R
und
.ft B
isam
.ft R
, sind Techniken der Zuweisung
von Tupeln zu festen Seiten einer Relation,
basierend auf den Schl\o'u"'sseldom\o'a"'nen der Tupel.
So enth\o'a"'lt jede Seite nur eine bestimmte
Untermenge der Relation.
.LP
Wenn ein neues Tupel in eine
.ft B
hash
.ft R
\-oder
.ft B
isam
.ft R
\-Relation eingef\o'u"'gt wird, stellt \*(yy\
zuerst fest, in welche Seite es geh\o'o"'rt
und \o'u"'berpr\o'u"'ft dann den verf\o'u"'gbaren Platz dieser Seite.
Wenn dort noch Platz ist, wird das Tupel
in dieser Seite untergebracht.
Wenn kein Platz ist,
wird eine \o'U"'berlauf-Seite erzeugt und
das Tupel dort platziert.
.LP
Die \o'U"'berlauf-Seite wird mit der Originalseite
verbunden.
Die Originalseite wird als Haupt-Seite bezeichnet.
Wenn die \o'U"'berlauf-Seite voll wird,
dann er\o'o"'ffnet \*(yy\
eine \o'U"'berlauf-Seite zu dieser.
Wir haben dann eine Haupt-Seite,
die mit einer \o'U"'berlauf-Seite verbunden ist,
welche wiederum mit einer anderen \o'U"'berlauf-Seite verbunden ist.
\o'U"'berlauf-Seiten werden dynamisch so hinzugef\o'u"'gt,
wie sie gebraucht werden.
.sp 2
.NH 4
.ft B
Spezifizierung des Freiraumes
.br
auf einer Seite (free space)
.ft R
.LP
Beim
.ft B
modify
.ft R
\-Statement k\o'o"'nnen sie angeben,
wieviel Platz zum Wachsen der Relation frei gehalten
werden soll.
Wie schon erw\o'a"'hnt,
ist eine Relation in Seiten gegliedert.
Der F\o'u"'llungsfaktor (
.ft B
fillfactor
.ft R
) spezifiziert,
wie weit jede Haupt-Seite belegt werden soll.
Diese Festlegung sollte n\o'a"'herungsweise darauf basieren, wieviele Tupel
in die Relation noch einzuf\o'u"'gen sind.
Zum Beispiel:
.IP
modify abgabe to isam on name where fillfactor = 100
.LP
Hier wird "modify" mitgeteilt,
dass jede Seite m\o'o"'glichst mit 100% gef\o'u"'llt
werden soll.
.IP
modify abgabe to isam on name where fillfactor = 25
.LP
bewirkt, dass jede Seite zu 25% gef\o'u"'llt, oder mit
anderen Worten, zu 75% leer ist.
Wir w\o'u"'rden so vorgehen, wenn wir etwa 1/4 der Daten
geladen h\o'a"'tten und annehmen, dass sie gleichm\o'a"'ssig
\o'u"'ber das Alphabet verteilt sind.
.LP
Merken sie sich, wenn der
.ft B
fillfactor
.ft R
nicht spezifiziert ist,
wird \*(yy\ einen vern\o'u"'nftigen Standardwert einsetzen.
Auch dann, wenn eine Seite gef\o'u"'llt ist, erzeugt \*(yy\
automatisch eine \o'U"'berlauf-Seite,
so dass niemals der Fall eintritt, dass eine Relation
nicht erweitert werden kann.
.LP
Wenn eine Relation zu
.ft B
hash
.ft R
modifiziert wird,
kann ein Parameter
.ft B
minpages
.ft R
(minimale Seitenanzahl)
spezifiziert werden.
.ft B
modify
.ft R
garantiert, dass mindestens
.ft B
minpage
.ft R
als Anzahl der Haupt-Seiten der Relation zugewiesen wird.
.LP
.ft B
modify
.ft R
berechnet, wieviele Haupt-Seiten ben\o'o"'tigt
werden, um die bestehenden Tupel unter Ber\o'u"'cksichtigung des
spezifizierten
.ft B
fillfactor
.ft R
so unterzubringen, dass keine \o'U"'berlauf-Seiten im Original notwendig sind.
Wenn die Zahl kleiner als
.ft B
minpages
.ft R
ist, dann wird
.ft B
minpages
.ft R
statt dieses Wertes verwendet.
.LP
Zum Beispiel:
.DS
modify abgabe to hash on name where fillfactor = 50,
minpages = 1
modify abgabe to hash on name where minpages = 150
.DE
Im ersten Fall garantieren wir, dass nicht mehr
Seiten als notwendig, bei 50% Belegung, benutzt werden.
Der zweite Fall ist typisch
f\o'u"'r die Modifizierung einer leeren oder fast
leeren Relation.
Wenn n\o'a"'herungsweise die maximale Gr\o'o"'sse
einer Relation bei ihrer Erstellung bekannt ist,
kann
.ft B
minpages
.ft R
dazu
benutzt werden, von Anfang an die Gr\o'o"'sse der Relation
auf dem Speicher freizuhalten.
.LP
Es ist noch eine andere Option f\o'u"'r
.ft B
hash
.ft R
zul\o'a"'ssig,
die sogenannte
.ft B
maxpages
.ft R
. Ihre Syntax ist die gleiche, wie f\o'u"'r
.ft B
minpages
.ft R
. Sie kann benutzt werden, um die maximale
Anzahl der Haupt-Seiten festzulegen.
.NH 4
.ft B
Verdichtung (compression)
.ft R
.LP
Die drei Speicherstrukturen
("heap", "hash", "isam") k\o'o"'nnen zus\o'a"'tzlich
durch
.ft B
compression
.ft R
erg\o'a"'nzt
werden.
Das geschieht, indem die
Speicherstrukturen als
.ft B
cheap
.ft R
,
.ft B
chash
.ft R
und
.ft B
cisam
.ft R
geschrieben werden.
Verdichtung reduziert
intern den Speicherplatz f\o'u"'r jedes Tupel.
Die gegenw\o'a"'rtige "compression"-Technik
unterdr\o'u"'ckt nachlaufende
.ft B
blanks
.ft R
(Leerzeichen) in
den Zeichenkettten-Dom\o'a"'nen.
Die Verwendung von
.ft B
compression
.ft R
verlangt niemals
mehr Platz und normalerweise wird Speicherplatz
gewonnen und k\o'o"'nnen die Ausf\o'u"'hrungszeit verk\o'u"'rzt.
Dazu ein Beispiel:
.IP
modify abgabe to cisam on name where fillfactor = 100
.LP
Es wird
.ft B
abgabe
.ft R
in eine komprimierte
.ft B
isam
.ft R
\-Struktur ver\o'a"'ndert und jede Seite
so weit als m\o'o"'glich gef\o'u"'llt.
Mit
.ft B
compression
.ft R
kann jedes Tupel
eine verschiedene, komprimierte L\o'a"'nge erhalten.
Dadurch muss die Zahl der Tupel,
die in einer Seite untergebracht werden k\o'o"'nnen,
davon abh\o'a"'ngen, wie erfolgreich die Verdichtung
ausgef\o'u"'hrt werden konnte.
.LP
Verdichtete Relationen sind aufwendiger zu aktualisieren.
Wenn ein
.ft B
replace
.ft R
auf eine oder mehrere Dom\o'a"'nen
ausgef\o'u"'hrt wird und das komprimierte Tupel war k\o'u"'rzer,
dann muss \*(yy\ einen neuen Platz f\o'u"'r das Tupel finden.
.NH 4
.ft B
Zwei Varianten zu einem Problem
.ft R
.LP
Zur Erinnerung, doppelte Tupel werden bei einer
.ft B
heap
.ft R
\-Relation nicht
gel\o'o"'scht.
Verschiedentlich ist es w\o'u"'nschenswert,
sie zu l\o'o"'schen und
eine
.ft B
heap
.ft R
\-Relation zu sortieren.
Ein Weg dazu ist,
die Relation zu
.ft B
isam
.ft R
unter Angabe
der Ordnungsmerkmale (
.ft B
keyed domains
.ft R
) zu modifizieren.
Eine Alternative dazu ist entweder die
Verwendung von
.ft B
heapsort
.ft R
oder
.ft B
cheapsort.
.ft R
Zum Beispiel:
.DS I
modify abgabe to heapsort on name, ext
.DE
.LP
Damit wird die Relation nach
"name" und dann nach "ext" sortiert.
Die Tupel werden zus\o'a"'tzlich nach den restlichen Dom\o'a"'nen,
in der Reihenfolge
ihrer urspr\o'u"'nglichen Angabe
beim
.ft B
create
.ft R
\-Statement, sortiert,
so dass in diesem Fall die Relation nach
"name", dann "ext" und dann "wert" sortiert wird.
Doppelte Tupel werden entfernt.
Die Relation wird als
.ft B
heap
.ft R
verlassen.
.ft B
heapsort
.ft R
und
.ft B
cheapsort
.ft R
sind vorgesehen
zum Sortieren von tempor\o'a"'ren Relationen, bevor sie gedruckt und
gel\o'o"'scht werden.
Dies ist wesentlich effektiver,
als die Modifizierung zu "isam",
da \*(yy\ kein "directory" erzeugt,
in dem die Schl\o'u"'sselinformationen f\o'u"'r
jede Seite enthalten sind.
Die Relation wird
.ft B
nicht
.ft R
in der Sortierung gehalten,
wenn anschliessend \o'A"'nderungen erfolgen.
.LP
Beispiele:
.br
Hier ist eine Sammlung von Beispielen und Erl\o'a"'uterungen
zur Abarbeitungseffizienz
jeder Query.
Die Queries basieren auf den
Relationen:
.DS I
teile(tnum, tname, farbe, gewicht, menge)
lieferung(lnum, pnum, jnum, liefdat, menge)
range of t is teile
range of l is lieferung
modify teile to hash on tnum
modify lieferung to hash on lnum,jnum
retrieve (t.all) where t.tnum = 10
.DE
\*(yy\ erkennt, dassteile
auf
.ft B
tnum
.ft R
via
.ft B
hash
.ft R
geschl\o'u"'sselt ist und geht direkt
auf die Seite, in der "teile" mit der Nummer 10 gespeichert ist.
.IP
retrieve (t.all) where t.tname = "magnetband"
.LP
\*(yy\ liest die vollst\o'a"'ndige Relation
und sucht den angegebenen "tname".
.IP
retrieve (t.all) where t.tnum < 10 and t.tnum > 5
.LP
\*(yy\ liest die vollst\o'a"'ndige Relation,
weil kein exakter Wert f\o'u"'r "tnum"
gegeben war.
.IP
retrieve (l.liefdat) where l.lnum = 471 and l.jnum = 1008
.LP
\*(yy\ erkennt, dass
.ft B
lieferung
.ft R
auf die Kombination von
.ft B
lnum
.ft R
und
.ft B
jnum
.ft R
via
.ft B
hash
.ft R
geschl\o'u"'sselt ist und
geht direkt zur richtigen Seite.
.DS I
retrieve (l.liefdat) where l.lnum = 471
.DE
.LP
\*(yy\ liest die gesamte
Relation.
.ft B
lieferung
.ft R
ist auf die
Kombination von
.ft B
lnum
.ft R
und
.ft B
jnum
.ft R
via
.ft B
hash
.ft R
geschl\o'u"'sselt.
Jedoch wurde \*(yy\ nur ein Wert von
beiden gegeben, es kann den
Vorteil der Speicherstruktur
nicht nutzen.
.DS I
retrieve (t.tname, l.liefdat) where
t.tnum = l.tnum and l.lnum = 471 and l.jnum = 1008
.DE
.LP
\*(yy\ nutzt den Vorteil beider
Speicherstrukturen.
Es findet zuerst alle Tupel
.ft B
l.tnum
.ft R
und
.ft B
l.liefdat
.ft R
, bei denen l.lnum = 471 und
l.jnum = 1008 ist.
Danach \o'u"'berpr\o'u"'ft es alle Tupel
t.tname, bei denen t.tnum gleich dem
korrekten Wert ist.
.LP
Dieses Beispiel illustriert, dass es manchmal
eine gute Idee ist, eine Relation mit den
Dom\o'a"'nen auf
.ft B
hash
.ft R
zu modifizieren, die mit
einer anderen Relation verbunden (
.ft B
joined
.ft R
) sind.
In diesem Fall w\o'a"'re das die Frage nach
t.tnum = l.tnum.
.LP
.ft B
Zusammengefasst:
.ft R
.LP
Um den Vorteil einer
.ft B
hash
.ft R
\-Struktur nutzen zu k\o'o"'nnen,
ben\o'o"'tigt \*(yy\ einen exakten Wert
f\o'u"'r jede Schl\o'u"'sseldom\o'a"'ne.
Ein exakter Wert ist soetwas
wie:
.IP
l.lnum = 471
.br
l.tnum = t.tnum
.LP
Ein exakter Wert ist aber nicht:
.IP
l.lnum >= 471
.br
(l.lnum = 10 or l.lnum = 20)
.LP
Wir wollen nun unsere Aufmerksamkeit
einigen F\o'a"'llen zur Anwendung von "isam" widmen:
.DS I
modify lieferung to isam on lnum,liefdat
retrieve (l.all) where l.lnum = 471
and l.liefdat > "75-12-31"
and l.liefdat < "77-01-01"
.DE
.LP
Da
.ft B
lieferung
.ft R
auf
.ft B
lnumund
.ft R
dann
auf
.ft B
liefdat
.ft R
sortiert ist, kann \*(yy\
den ganzen Vorteil einer
.ft B
isam
.ft R
\-Struktur zur Lokalisierung des Bereichs
von
.ft B
lieferung
.ft R
, der die Query befriedigt,
nutzen.
.IP
retrieve (l.all) where l.lnum = 471
.LP
Im Gegensatz zu
.ft B
hash
.ft R
, kann eine
.ft B
isam
.ft R
\-Struktur
noch verwendet werden, wenn nur der erste Schl\o'u"'ssel
beschafft wird.
.IP
retrieve (l.all) where l.lnum > 400 and l.lnum < 500
.LP
Wieder wird \*(yy\ den Vorteil der Struktur nutzen.
.DS I
retrieve (l.all) where l.liefdat >= "75-12-31" and
l.liefdat <= "77-01-01"
.DE
.LP
Hier wird \*(yy\ die vollst\o'a"'ndige Relation lesen.
Das geschieht, weil der erste Schl\o'u"'ssel (lnum) nicht
in der Query vorgeschlagen wurde.
.LP
.ft B
Zusammengefasst:
.ft R
.LP
.ft B
isam
.ft R
gestattet die Beschleunigung des Zugriffs
sowohl zu exakten Werten, als auch zu
Wertebereichen.
Das funktioniert solange, wie wenigstens der erste Schl\o'u"'ssel
vom Nutzer vorgegeben wird.
.LP
Um festzustellen, wo die Tupel
in einer "isam"-Relation stehen,
durchsucht \*(yy\ das "isam-directory" dieser
Relation.
Wenn eine Relation nach
.ft B
isam
.ft R
modifiziert wird,
werden die Tupel zuerst sortiert und dabei die
doppelten Tupel
gel\o'o"'scht.
Als n\o'a"'chstes wird die Relation
(unter Verwendung des
.ft B
fillfactor
.ft R
), beginnend mit
Block 0, 1, 2... und so weiter, entsprechend der
ben\o'o"'tigten Seitenanzahl gef\o'u"'llt.
.LP
Jetzt wird das
.ft B
directory
.ft R
aufgebaut.
Die Schl\o'u"'sseldom\o'a"'nen des ersten Tupels
jeder Seite werden eingesammelt und
in ein
.ft B
directory
.ft R
(in der Relation
auf Platte gespeichert) gebracht.
Das
.ft B
directory
.ft R
wird nicht eher
ge\o'a"'ndert, als bis die n\o'a"'chste Modifizierung angewiesen wurde.
.LP
Wann immer ein Tupel zu einer Relation hinzugef\o'u"'gt wird,
wird das
.ft B
directory
.ft R
durchsucht, um die Seite zu finden,
in der das neue Tupel untergebracht werden muss.
Damit bleiben in dieser Seite die einzelnen
Tupel
.ft B
nicht
.ft R
genau sortiert.
Das ist auch mit der n\o'a"'herungsweisen (
.ft B
approximately
.ft R
) Sortierung im obigen Kapitel gemeint.
.NH 4
.ft B
Vergleich von heap, hash und isam
.ft R
.LP
Wir wollen einmal die Vor- und Nachteile
der einzelnen Speicherstrukturen
vergleichen.
Eine Relation wird immer als
.ft B
heap
.ft R
erzeugt.
.ft B
heap
.ft R
ist die g\o'u"'nstigste
Struktur f\o'u"'r das erstmalige
Auff\o'u"'llen einer Relation bei Verwendung von
.ft B
copy
.ft R
oder
.ft B
append.
.ft R
.LP
Der Platz von gel\o'o"'schten Tupeln bei
.ft B
heap
.ft R
wird nur in der letzten Seite wiederverwendet.
Ein Test auf doppelte Tupel wird bei
.ft B
heap
.ft R
\-Relationen nicht ausgef\o'u"'hrt.
.LP
"hash" ist vorteilhaft f\o'u"'r die Lokalisierung von Tupeln,
sofern sie in der Qualifikation (
.ft B
where
.ft R
\-Klausel) durch einen exakten Wert
referenziert werden.
Die Haupt-Seite von Tupeln kann mit einem vorgegebenen
Wert leicht ermittelt werden.
.LP
.ft B
isam
.ft R
ist gebr\o'a"'uchlich f\o'u"'r exakte Werte und Wertebereiche.
Weil das "isam-directory" durchsucht werden muss,
um die Tupel zu lokalisieren, ist
.ft B
isam
.ft R
nicht so effektiv wie
.ft B
hash.
.ft R
.NH 4
.ft B
\o'U"'berlauf-Seiten
.ft R
.LP
Wenn ein Tupel eingef\o'u"'gt wird
und sich kein freier Raum mehr auf der
Haupt-Seite einer Relation befindet, dann wird eine
\o'U"'berlauf-Seite erzeugt.
Wenn mehr Tupel eingef\o'u"'gt werden, als eine \o'U"'berlauf-Seite aufnimmt,
werden weitere Seiten angeh\o'a"'ngt.
Obwohl \o'U"'berlauf-Seiten notwendig sind, vermindern sie
die Geschwindigkeit
des Systems bei Ausf\o'u"'hrung
von Recherchen und
.ft B
update
.ft R
's.
.LP
Beispielsweise wollen wir annehmen das "lieferung"
auf
.ft B
lnum
.ft R
via
.ft B
hash
.ft R
geschl\o'u"'sselt wird und 10 Haupt-
Seiten hat.
Angenommen der Wert lnum = 3 f\o'a"'llt auf Seite 7.
Um alle Tupel mit lnum = 3 zu finden, bezieht \*(yy\ in die Suche
die Haupt-Seite 7 und alle zu Seite 7 geh\o'o"'rigen \o'U"'berlauf-
Seiten ein
(, sofern es welche gibt).
Je mehr \o'U"'berlauf-Seiten einbezogen werden m\o'u"'ssen,
um so mehr Zeit wird ben\o'o"'tigt, um nach lnum = 3 zu recherchieren.
Um doppelte Tupel bei
.ft B
isam
.ft R
und
.ft B
hash
.ft R
l\o'o"'schen zu k\o'o"'nnen,
muss ebenfalls bei
.ft B
append
.ft R
und
.ft B
replace
.ft R
die Suche
\o'u"'ber alle Seiten ausgef\o'u"'hrt werden.
.LP
Wenn eine
.ft B
hash
.ft R
\- oder
.ft B
isam
.ft R
\-Relation zu viele \o'U"'berlauf-
Seiten
hat, empfiehlt es sich, sie erneut zu
.ft B
hash
.ft R
oder
.ft B
isam
.ft R
zu modifizieren.
Damit wird die Relation bereinigt
und es werden soviele \o'U"'berlauf-Seiten als m\o'o"'glich eli\%miniert.
.NH 4
.ft B
Eindeutige Schl\o'u"'ssel
.ft R
.LP
Bei der Wahl des Schl\o'u"'ssels (
.ft B
keyed domain
.ft R
) einer Relation
ist es w\o'u"'nschenswert,
weitgehende
Eindeutigkeit zu erreichen.
Beispielsweise treten bei Personalnummern
keine doppelten Nummern auf,
w\o'a"'hrend bei solchen Begriffen, wie
"Farbe" nur einige wenige
verschiedene Werte und
manchmal, wie bei "Geschlecht"
bekanntermassen nur zwei Werte auftreten
k\o'o"'nnen.
.LP
Wenn eine Relation auf die Dom\o'a"'ne "geschlecht"
via
.ft B
hash
.ft R
geschl\o'u"'sselt wird, k\o'o"'nnen
sie erwarten, dass alle m\o'a"'nnlichen Objekte auf einer Haupt-Seite und dazugeh\o'o"'rigen
\o'U"'berlauf-Seiten untergebracht werden, ebenso auch alle weiblichen.
Mit einer
.ft B
hash
.ft R
\-Relation gibt es keine L\o'o"'sung dieses
Problems.
Es muss ein Kompromiss zwischen
den in der Qualifikation am h\o'a"'ufigsten
verwendeten
Schl\o'u"'sseln und der Eindeutigkeit der
Schl\o'u"'sselwerte gefunden werden.
.LP
Da der Vorteil der
.ft B
isam
.ft R
\-Struktur
solange genutzt werden kann, als zumindest der
erste Schl\o'u"'ssel vorgegeben wird, k\o'o"'nnen
unter Umst\o'a"'nden weitere
Dom\o'a"'nen zum Schl\o'u"'ssel
hinzugef\o'u"'gt werden,
um die Eindeutigkeit desselben zu erh\o'o"'hen.
Nehmen wir beispielsweise an, dass die
Relation "lieferung" nur 10 verschiedene Lieferanten, aber tausende Tupel hat.
Die Wahl einer
.ft B
isam
.ft R
\-Struktur, mit den Schl\o'u"'sseln
.ft B
lnum
.ft R
und
.ft B
jnum
.ft R
wird wahrscheinlich viel mehr eindeutige Schl\o'u"'ssel ergeben.
Wie auch immer, die Gr\o'o"'sse des "directories" wird
zunehmen und folglich dauert die
Suche immer l\o'a"'nger.
Wenn sie zur Erh\o'o"'hung der
Eindeutigkeit des Schl\o'u"'ssels weitere
Dom\o'a"'nen zu Schl\o'u"'ssel hinzuf\o'u"'gen,
versuchen sie
m\o'o"'glichst die k\o'u"'rzesten auszuw\o'a"'hlen.
.NH 4
.ft B
Systemkataloge
.ft R
.LP
\*(yy\ verwendet sieben Kataloge
(
.ft B
relation
.ft R
,
.ft B
references
.ft R
,
.ft B
attribute
.ft R
,
.ft B
indexes
.ft R
,
.ft B
tree
.ft R
,
.ft B
protect
.ft R
und
.ft B
intgrities
.ft R
), um Datenbanken
zu verwalten und zu organisieren.
Der
.ft B
relation
.ft R
\-Katalog hat ein Tupel f\o'u"'r
jede Relation in der Datenbank.
Der
.ft B
attribute
.ft R
\-Katalog hat ein Tupel
f\o'u"'r jedes Attribut in jeder
Relation.
Der
.ft B
indexes
.ft R
\-Katalog
hat ein Tupel f\o'u"'r jeden
Sekund\o'a"'rindex.
.LP
\*(yy\ greift auf diese Kataloge
in einer bestimmten Art und Weise zu.
Das Programm
.ft B
sysmod
.ft R
sollte verwendet werden,
um diese Kataloge auf vordefinierten
Dom\o'a"'nen via
.ft B
hash
.ft R
zu modifizieren.
Um
.ft B
sysmod
.ft R
anzuwenden, gibt der
Datenbankadministrator ein
.sp 1
% sysmod Datenbankname
.sp 1
.ft B
sysmod
.ft R
sollte unmittelbar
nach der Gr\o'u"'ndung einer Datenbank
abgearbeitet werden, bzw. nachdem die Relationen erzeugt wurden. Die Datenbank
ist nun aufgebaut.
Es ist nicht ausreichend,
.ft B
sysmod
.ft R
einmal zu starten und es dann zu vergessen.
Ein wiederholter Start von
.ft B
sysmod
.ft R
\o'u"'berarbeitet
die Systemkataloge.
Durch die Anwendung werden die
meisten \o'U"'berlauf-Seiten gel\o'o"'scht
und die Systemantwortzeit in vielerlei Hinsicht
verbessert.
.NH 3
.ft B
Sekund\o'a"'rindizes
.ft R
.LP
Die Verwendung einer
.ft B
isam
.ft R
- oder
.ft B
hash
.ft R
\-Struktur
gestattet, schnell die Tupel einer
Relation zu finden und die Werte entsprechend
der Schl\o'u"'seldom\o'a"'nen zu \o'u"'bergeben.
Manchmal ist das aber nicht genug.
Nehmen wir beispielsweise an,
wir h\o'a"'tten die "abgabe"-Relation
.IP
abgabe(name, wert, ext)
.LP
auf
.ft B
name
.ft R
via
.ft B
hash
.ft R
geschl\o'u"'sselt.
Es ergibt sich ein schneller Zugriff
f\o'u"'r Queries mit einem exakten Wert f\o'u"'r
.ft B
name
.ft R
in der Qualifikation (
.ft B
where
.ft R
\-Klausel).
Doch was ist, falls wir den
Queries einen exakten Wert f\o'u"'r
.ft B
ext
.ft R
\o'u"'bergeben wollen?
.LP
.ft B
abgabe
.ft R
kann entweder f\o'u"'r
.ft B
name
.ft R
oder
.ft B
ext
.ft R
auf
.ft B
hash
.ft R
gesetzt werden, wir k\o'o"'nnen w\o'a"'hlen,
was anwendungsfreundlicher ist
und
.ft B
abgabe
.ft R
auf diese Dom\o'a"'ne setzen.
Die andere Dom\o'a"'ne (sagen wir "ext") kann einen
Sekund\o'a"'rindex (secondary index) haben.
Ein Sekund\o'a"'rindex ist eine Relation, die die
exakte Position der Tupel zu jedem
.ft B
ext
.ft R
in der Relation
.ft B
abgabe
.ft R
enth\o'a"'lt.
.LP
Das Kommando zur Erzeugung eines
Sekund\o'a"'rindexes ist:
.IP
index on abgabe is abgext (ext)
.LP
Die allgemeine Form lautet:
.br
.sp 1
index on relation_name is secondary_index_name (domains)
.sp 1
Nun beauftragen wir \*(yy\,
einen Sekund\o'a"'rindex in der Relation
.ft B
abgabe
.ft R
zu erzeugen.
Die Dom\o'a"'ne die indiziert werden soll, ist
.ft B
ext.
.ft R
Indizes werden in drei Schritten gebildet:
.IP 1.
.ft B
abgext
.ft R
erzeugt ein
.ft B
heap.
.ft R
.IP 2.
F\o'u"'r jedes
Tupel in
.ft B
abgabe
.ft R
, wird ein Tupel
mit dem Wert f\o'u"'r
.ft B
ext
.ft R
und der genauen Position
des korrespondierenden Tupels in
.ft B
abgabe
.ft R
in
.ft B
abgext
.ft R
eingef\o'u"'gt.
.IP 3.
Standardm\o'a"'ssig wird
.ft B
abgext
.ft R
zu
.ft B
isam
.ft R
modifiziert.
.LP
Wenn wir jetzt die Query
.DS
range of a is abgabe
retrieve(a.wert) where a.ext = 207
.DE
starten, wird \*(yy\ automatisch zuerst in
.ft B
abgext
.ft R
nachsehen, um ext = 207 zu finden.
Wenn es dort ein Tupel findet, geht es direkt
zum Tupel in der
.ft B
abgabe
.ft R
\-Relation.
Da
.ft B
abgext
.ft R
auf
.ft B
isam
.ft R
f\o'u"'r
.ft B
ext
.ft R
gesetzt wurde, wird die
Suche nach ext = 207 nat\o'u"'rlich ebenfalls schnell
erledigt sein.
.LP
Wenn sie die Query
.IP
retrieve(a.wert) where a.name = "frank"
.LP
starten, dann wird \*(yy\ in der
.ft B
hash
.ft R
\-Struktur der Relation
.ft B
abgabe
.ft R
versuchen fortzufahren, um die qualifizierten Tupel zu lokalisieren.
.LP
Da Sekund\o'a"'rindizes eigenst\o'a"'ndige Relationen sind,
k\o'o"'nnen sie auch (entweder)
.ft B
hash, isam, chash
.ft R
oder
.ft B
cisam
.ft R
sein.
Es ist nicht vern\o'u"'nftig, einen Sekund\o'a"'rindex auf
.ft B
heap
.ft R
zu setzen.
.LP
Die Beurteilung, welche Struktur geeignet ist, ergibt sich
aus den Erkenntnissen,
die zuvor diskutiert wurden:
.sp 1
Werden die Dom\o'a"'nen durch exakte Werte referenziert?
.br
Werden sie durch Wertebereiche referenziert?
.br
etc.
.LP
In dem Fall, wo die
.ft B
ext
.ft R
\-Dom\o'a"'ne
durch exakte Werte referenziert und
die Relation beinahe gef\o'u"'llt ist, k\o'o"'nnen wir folgendes tun:
.DS I
modify abgext to hash on ext where fillfactor = 100
and minpages = 1
.DE
Sekund\o'a"'rindizes stellen in \*(yy\
einen Weg dar, \o'u"'ber Dom\o'a"'nen
auf Tupel zuzugreifen,
die keine Schl\o'u"'ssel sind.
Eine Relation kann eine beliebige Anzahl von
Sekund\o'a"'rindizes haben und ausserdem kann
jeder Sekund\o'a"'rindex ein Index auf bis
zu sechs Dom\o'a"'nen einer Prim\o'a"'rrelation sein.
.LP
Wenn ein Tupel in einer Prim\o'a"'rrelation
ersetzt (replaced), gel\o'o"'scht (deleted)
oder angeh\o'a"'ngt (appended) wird,
m\o'u"'ssen alle Sekund\o'a"'rindizes auch aktualisiert
werden,
die Indizes
kosten was.
Sie erh\o'o"'hen den
Aufwand zur Aktualisierung
der Prim\o'a"'rrelation, aber
sie k\o'o"'nnen den Aufwand zum Auffinden von Tupel
in der Prim\o'a"'rrelation erheblich senken.
.LP
Ob ein Sekund\o'a"'rindex die Geschwinigkeit
der Recherche erh\o'o"'ht oder nicht, h\o'a"'ngt von
der Eindeutigkeit der Werte
der indizierten Dom\o'a"'nen
ab.
Die Hauptfrage bleibt, ob eine indirekte
Suche \o'u"'ber den Index effizienter als
das Durch\%suchen der gesamten
Prim\o'a"'rrelation ist.
Allgemein ist es effektiver,
wenn die Anzahl der Tupel, die die Qualifikation (
where
\-Klausel)
erf\o'u"'llen, kleiner ist, als die Gesamtzahl der Seiten
(Haupt- und \o'U"'berlauf-Seiten) der
Prim\o'a"'rrelation.
.LP
Beispielsweise wollen wir h\o'a"'ufig alle
Personen wissen, die weniger als f\o'u"'nf Mark
verdienen, dann beachten sie den erzeugten Index
.IP
index on abgabe is abgwert (wert)
.LP
Standardm\o'a"'ssig wird
.ft B
abgwert
.ft R
eine
.ft B
isam
.ft R
-Struktur auf
.ft B
wert.
.ft R
Wenn \*(yy\ die Query
.IP
retrieve(a.name) where a.wert < 5.0
.LP
ausf\o'u"'hrt, wird auf a.wert < 5.0 im
Sekund\o'a"'rindex lokalisiert und f\o'u"'r jedes Tupel das
gefunden wird, das korrespondierende Tupel
in
.ft B
abgabe
.ft R
geholt.
Die Tupel in
.ft B
abgwert
.ft R
sind nach
wert sortiert, die Tupel in
.ft B
abgabe
.ft R
jedoch nicht.
Damit wird im Allgemeinen jedes Tupel
von
.ft B
abgabe
.ft R
\o'u"'ber
.ft B
abgwert
.ft R
adressiert,
die sich aber auf verschiedenen Seiten befinden.
Solche Recherchen \o'u"'ber einen Sekund\o'a"'rindex
erfordern mehr Seitenleseoperationen (IO's), als
wenn die Prim\o'a"'rrelation
.ft B
abgabe
.ft R
sequentiell gelesen worden w\o'a"'re.
In solchen F\o'a"'llen ist die Erzeugung
eines Sekund\o'a"'rindex' nicht zu empfehlen.
.NH 3
.ft B
Wiederherstellung (Recovery) und
.br
Aktualisierung (Update)
.ft R
.LP
.NH 4
.ft B
Einf\o'u"'hrung
.ft R
.LP
\*(yy\ wurde sorgf\o'a"'ltig entworfen, um
die Integrit\o'a"'t der Datenbank bei bestimmten
Arten von Systemfehlern
zu sch\o'u"'tzen.
Um das \*(yy\ zu erm\o'o"'glichen,
wird bei der Ausf\o'u"'hrung von Aenderungen mit
dem sogenannten
.ft B
deferred update
.ft R
(verz\o'o"'gerte Aktualisierung)
oder
.ft B
batchfile update
.ft R
(gepufferte Dateiaktualisierung) gearbeitet.
Weiterhin gibt es in \*(yy\ zwei
Programme
.ft B
restore
.ft R
(wiederherstellen) und
.ft B
purge
.ft R
(reinigen), die verwendet
werden k\o'o"'nnen,
um nach aufgetretenen Systemfehlern die Datenbank
zu testen und wieder in Ordnung zu bringen.
Wir wollen zuerst diskutieren,
wie "deferred updates" erzeugt und ausgef\o'u"'hrt
werden und uns danach mit der Verwendung von
.ft B
purge
.ft R
und
.ft B
restore
.ft R
besch\o'a"'ftigen.
.NH 4
.ft B
Deferred Update und Batch Update
.ft R
.LP
.NH 5
.ft B
\o'U"'bersicht
.ft R
.LP
.ft B
deferred update
.ft R
kann man mit verz\o'o"'gerter Aktualisierung
\o'u"'bersetzen.
.IP
Ein
.ft B
append
.ft R
\-,
.ft B
replace
.ft R
\- oder
.ft B
delete
.ft R
\-Kommando wird
in vier Schritten ausgef\o'u"'hrt:
.IP 1.
Ein leeres
.ft B
batchfile
.ft R
(Pufferfile) wird erzeugt.
.IP 2.
Das Kommando wird ausgef\o'u"'hrt
und jede Aenderung der Relation wird in
das
.ft B
batchfile
.ft R
geschrieben.
.IP 3.
Das
.ft B
batchfile
.ft R
wird gelesen und
die Relation und ihre Sekund\o'a"'rindizes (falls vorhanden)
werden aktualisiert.
.IP 4.
Das
.ft B
batchfile
.ft R
wird zerst\o'o"'rt und \*(yy\
kehrt zum Nutzer zur\o'u"'ck.
.LP
Das
.ft B
deferred update
.ft R
verz\o'o"'gert die wirkliche
\o'A"'nderung bis zum tats\o'a"'chlichen Ende
der Query.
Diese Vorgehensweise hat drei Vorteile:
.NH 5
.ft B
Beseitigung der Auswirkung von Systemfehlern
.ft R
.LP
Falls das System w\o'a"'hrend einer Aktualisierung
zusammenbricht (
.ft B
crash
.ft R
),
kann das \*(yy\-Recovery-Programm entscheiden, entweder
die \o'A"'nderung zu Ende auszuf\o'u"'hren oder durch
.ft B
back out
.ft R
(Ablehnung) die \o'A"'nderung zur\o'u"'ckzusetzen und die
Relation in dem Zustand zu belassen, in dem sie sich vorher
befand.
.NH 4
.ft B
Die Verhinderung endloser Queries
.ft R
.LP
Falls
.ft B
abgabe
.ft R
ein
.ft B
heap
.ft R
w\o'a"'re und die Query
.DS
range of a is abgabe
append to abgabe(a.all)
.DE
w\o'u"'rde ohne
.ft B
deferred update
.ft R
ausgef\o'u"'hrt,
dann wird die Ausf\o'u"'hrung erst bei \o'U"'berlauf
des Plattenspeichers bzw. wenn kein freier
Platz mehr vorhanden ist, beendet!
Das geschieht deshalb, weil \*(yy\
mit dem Lesen der Relation vorn anf\o'a"'ngt
und jedes Tupel an das Ende
angeh\o'a"'ngt (append) wird.
Es w\o'u"'rde bald beginnen, die Tupel zu lesen,
die kurz vorher angeh\o'a"'ngt worden sind und
unendlich fortsetzen, um
das Ende zu erhaschen, das immer
wieder entschwindet.
.LP
Obwohl diese Query sicherlich nicht
typisch ist, illu\%striert sie das Problem.
Es gibt bestimmte Klassen von Queries,
bei denen Probleme durch aktualisierte
Ablagen ber\o'u"'hrt werden, die
nicht pr\o'a"'zise definiert sind.
Mit dem
.ft B
deferred update
.ft R
kann garantiert werden, dass die Ergebnisse konsistent
und logisch sind.
.NH 5
.ft B
Beschleunigung der \o'A"'nderungszeiten
.br
von Sekund\o'a"'rindizes
.ft R
.LP
Sekund\o'a"'rindizes k\o'o"'nnen schneller
aktualisiert werden,
wenn alle \o'A"'nderungen auf einmal ausgef\o'u"'hrt werden,
anstatt jede \o'A"'nderung einzeln.
Das schliesst auch den Schutz ein,
dass der Sekund\o'a"'rindex die Uebereinstimmung
mit der Prim\o'a"'rrelation beh\o'a"'lt.
.NH 5
.ft B
Abschalten des deferred update
.ft R
.LP
Wenn sie von diesen Argumenten nicht
\o'u"'berzeugt wurden, ge\%stattet \*(yy\
auch, das "deferred update" abzuschalten!
Tats\o'a"'chlich gibt es sicher F\o'a"'lle, wo es
angebracht ist (aber nat\o'u"'rlich
nicht notwendig), die \o'A"'nderung
direkt auszuf\o'u"'hren, d.h. die Relation wird
w\o'a"'hrend der Query ge\o'a"'ndert.
.LP
Um die direkte \o'A"'nderung anzuwenden, m\o'u"'ssen sie
die Erlaubnis des \*(yy\-
Systemadministrators haben.
Wenn sie das
.ft B
-b
.ft R
\-Flag beim Start von \*(yy\ verwenden,
wird das
.ft B
deferred update
.ft R
ausgeschaltet.
.sp 1
% quel -b meindb
.sp 1
\*(yy\ verwendet die direkte \o'A"'nderung nur f\o'u"'r Relationen ohne
Sekund\o'a"'rindizes.
Die Anwendung des
.ft B
deferred update
.ft R
wird f\o'u"'r Relationen
mit Sekund\o'a"'rindex
stillschweigend immer benutzt.
Bei Nutzung des
.ft B
-b
.ft R
\-Flag m\o'u"'ssen sie
auf die oben genannten Vorteile der verzichten.
In den meisten F\o'a"'llen sollte man
das
.ft B
-b
.ft R
\-Flag
.ft B
nicht anwenden.
.ft R
.sp 1
Wenn sie \*(yy\ so benutzen, dass
sie interaktiv nur ein Tupel
eingeben oder \o'a"'ndern, ist
es etwas g\o'u"'nstiger das
.ft B
deferred update
.ft R
abzuschalten.
Wenn das System w\o'a"'hrend einer \o'A"'nderung
zusammenbricht, ist die eingebende Person
in der Lage, festzustellen, ob das
Tupel ge\o'a"'ndert wurde oder nicht.
.NH 4
.ft B
Restore
.ft R
.LP
\*(yy\ ist so entworfen, dass nach fast allen
Typen von Systemabst\o'u"'rzen
ein Recovery m\o'o"'glich ist,
falls das \*(xx\-File-System
konsistent geblieben ist.
Das betrifft die \o'A"'nderungskommandos, das
.ft B
update
.ft R
\-,
.ft B
create
.ft R
\-,
.ft B
destroy
.ft R
\-,
.ft B
modify
.ft R
\- und auch das
.ft B
index
.ft R
\-Kommando.
.LP
\*(yy\ wurde auf
.ft B
perfekte Sicherheit
.ft R
entworfen.
Wenn irgend\%eine Nicht\o'u"'bereinstimmung entdeckt
oder irgendein Mangel von \*(xx\ zur\o'u"'ckgegeben
wurde,
generiert \*(yy\ eine System-Error-Mitteilung
(SYSERR) und bricht ab.
.LP
Wenn \*(xx\ zusammenbricht, w\o'a"'hrend \*(yy\
arbeitet, oder ein \*(yy\-SYSERR auftritt,
ist es generell sinnvoll,
dass der Datenbankadministrator das Kommando
.sp 1
% restore data_base_name
.sp 1
gibt. Das Restore-Programm erf\o'u"'llt
folgende Funktionen:
.IP 1.
Es pr\o'u"'ft die
.ft B
"batchfiles".
.ft R
Wenn es eins findet, pr\o'u"'ft es jedes,
um festzustellen, ob es komplett ist.
Wenn der System-crash auftrat, w\o'a"'hrend
das
.ft B
batchfile
.ft R
gerade gelesen und auf die Datenbank ausgegeben wurde,
dann holt
.ft B
restore
.ft R
die \o'A"'nderung nach.
Falls andererseits das
.ft B
batchfile
.ft R
noch
nicht vollst\o'a"'ndig war, wird es einfach zerst\o'o"'rt,
damit ist es so, als w\o'a"'re die Query noch nicht ausgef\o'u"'hrt.
.IP 2.
Test auf unvollst\o'a"'ndige
.ft B
modify
.ft R
\-Kommandos.
Dieser Schritt ist entscheidend.
Er garantiert, dass sie entweder die Relation
so vorfinden, wie vor der Modifikation,
oder
.ft B
restore
.ft R
ist in der Lage das
.ft B
modify
.ft R
-Kommando zu vervollst\o'a"'ndigen.
.ft B
modify
.ft R
arbeitet so, dass es eine neue Kopie
der Relation in der neuen Struktur erzeugt.
Wenn es dann fertig ist, ersetzt es die alte
Relation, es speichert die neuen Informationen in ein
.ft B
modify batchfile
.ft R
(modifiziertes Pufferfile).
Das bef\o'a"'higt
.ft B
restore
.ft R
den Stand unfertiger Modifizierungen
festzustellen.
.IP 3.
Test auf die Uebereinstimmung der Systemrelationen.
Dieser Test wird verwendet, um
.ft B
destroy
.ft R
\-Kommandos zu vervollst\o'a"'ndigen,
.ft B
create
.ft R
\-Kommandos zur\o'u"'ckzusetzen
und
.ft B
index
.ft R
\-Kommandos zur\o'u"'ckzusetzen oder zu vervollst\o'a"'ndigen,
die durch einen System-crash unterbrochen wurden.
.IP 4.
Bereinigung tempor\o'a"'rer Relationen und Files.
.ft B
restore
.ft R
f\o'u"'hrt das
.ft B
purge
.ft R
\-Programm aus,
um tempor\o'a"'re Relationen und tempor\o'a"'re
Files, die vom System erzeugt wurden, zu l\o'o"'schen.
.ft B
purge
.ft R
wird etwas sp\o'a"'ter detaillierter diskutiert.
.LP
.ft B
restore
.ft R
kann dem Nutzer nicht sagen, welche Queries ausgef\o'u"'hrt
wurden und welche nicht.
Es kann nur die Queries erkennen, die gerade liefen, als der
crash erfolgte.
Falls Queries auch gerettet werden sollen,
ist es am besten, sie in ein File auszugeben.
Gegebenenfalls kann der Monitor jede Query oder eine Folge von Queries ausgeben und der Nutzer sp\o'a"'ter erkennen, welche
Queries
ausgef\o'u"'hrt wurden.
.LP
.ft B
restore
.ft R
hat mehrere Optionen zur Erweiterung
seiner Anwendbarkeit,
die durch Flags spezifiziert werden.
Die Optionen erm\o'o"'glichen:
.IP -a
fragt vor der Ausf\o'u"'hrung
.IP -f
verwendet f\o'u"'r
.ft B
purge
.ft R
; l\o'o"'scht
tempor\o'a"'re Files;
.IP -p
verwendet f\o'u"'r
.ft B
purge
.ft R
; l\o'o"'scht
verfallene Relationen;
.IP no_database
erneuert alle Datenbanken,
f\o'u"'r die sie DBA sind;
.LP
Von diesen Optionen ist
.ft B
-a
.ft R
die wichtigste.
Es kann geschehen, dass durch einen \*(xx\-crash eine
Seite des Systemkataloges besch\o'a"'digt
wird.
Das kann dazu f\o'u"'hren, dass
.ft B
restore
.ft R
eine Relation
austr\o'a"'gt (zerst\o'o"'rt).
In Wirklich\%keit wollen sie lieber zur Beseitigung des Problems
die Systemkataloge flicken (
.ft B
patch
.ft R
), um korrekt
weiterarbeiten zu k\o'o"'nnen.
Aber kein
.ft B
restore
.ft R
\-Programm kann f\o'u"'r alle
M\o'o"'glichkeiten eingerichtet werden.
Es ist deshalb kein Ersatz (gl\o'u"'cklicherweise !)
f\o'u"'r den Menschen.
.LP
Wenn
.ft B
-a
.ft R
spezifiziert ist, teilt
.ft B
restore
.ft R
mit, was es
tun w\o'u"'rde und fragt dazu nach der
Erlaubnis.
Es liest von Standard-Input und
akzeptiert
.ft B
y
.ft R
als Anweisung zur Ausf\o'u"'hrung und
die \o'u"'brigen Zeichen als Ablehnung.
Beispielsweise, wenn bei
.ft B
restore
.ft R
vor Ausf\o'u"'hrung gefragt
werden soll, geben sie
.IP
restore -a meindb
.LP
Wenn sie auf alle Fragen
.ft B
nein
.ft R
antworten
wollen, so geben sie
.IP
restore -a meindb </dev/null
.LP
Die Verwendung des
.ft B
-a
.ft R
\-Flag f\o'u"'hrt dazu, dass
.ft B
restore
.ft R
nach der Genehmigung zur
Ausf\o'u"'hrung der Bereinigung fragt,
beispielsweise,
wenn es eine Dom\o'a"'ne findet ohne dazugeh\o'o"'rige
Relation
oder, wenn es einen Sekund\o'a"'rindex ohne
Prim\o'a"'rrelation findet,
usw.
.LP
Es gab kaum einen System-crash, den \*(yy\
nicht bereinigen kann.
Damit ist nicht gemeint, dass sich solche Situationen
nicht ergeben k\o'o"'nnen-
sie sollten nicht sorglos werden.
Es muss daran erinnert werden, dass
.ft B
restore
.ft R
kein Ersatz
f\o'u"'r das periodische Anlegen eines
.ft B
backing_up
.ft R
(Sicherheitskopie) ist und
diese Funktion auch nicht erf\o'u"'llen soll.
.NH 4
.ft B
Purge
.ft R
.LP
.ft B
purge
.ft R
kann verwendet werden, um Ausk\o'u"'nfte \o'u"'ber
verfallene Relationen zu geben, tempor\o'a"'re Systemrelationen
zu streichen,
fremde Files zu l\o'o"'schen und verfallene
Relationen auszutragen.
Um
.ft B
purge
.ft R
verwenden zu k\o'o"'nnen, m\o'u"'ssen sie
der DBA der Datenbank sein.
.IP
% purge meindb
.LP
.ft B
purge
.ft R
hat mehrere Optionen, die durch
Flags spezifiziert werden und folgendermassen
lauten:
.IP -f
(Standard ausgeschaltet);
L\o'o"'schen aller fremden Files;
Jedes File wird angezeigt und dann gel\o'o"'scht.
Wenn
.ft B
-f
.ft R
nicht spezifiziert ist, wird es nur
angezeigt.
.IP -p
(Standard ausgeschaltet);
Zerst\o'o"'rung aller verfallenen Relationen;
Jede verfallene Relation wird angezeigt und
wenn
.ft B
-p
.ft R
spezifiziert ist, zerst\o'o"'rt.
.LP
.ft B
purge
.ft R
zerst\o'o"'rt Relationen und Files immer dann,
wenn sie im \*(yy\-System tempor\o'a"'rer Art sind.
Bei der Ausf\o'u"'hrung von Multi-Variablen-
Queries und Queries mit Aggregierungsfunktionen erzeugt
\*(yy\ gew\o'o"'hnlich tempor\o'a"'re Relationen
mit Zwischenergebnissen.
Diese Relationen beginnen immer mit den
Zeichen
.ft B
SYS.
.ft R
Auch einige andere \*(yy\-Kommandos erzeugen
tempor\o'a"'re Files, die
mit
.ft B
SYS
.ft R
beginnen.
Bei normalem Ablauf werden sie bei Beendigung
gel\o'o"'scht.
Wenn ein System-crash auftritt, k\o'o"'nnte das unterbleiben.
.ft B
purge
.ft R
bereinigt die tempor\o'a"'ren Files des Systems,
die Nutzerrelationen nur dann, wenn
es explizit dazu aufgefordert wird.