3108 lines
58 KiB
Plaintext
3108 lines
58 KiB
Plaintext
.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.
|