Java/JDBC Implementierung und Auswertung von Algorithmen zur

Werbung
Java/JDBC Implementierung und
Auswertung von Algorithmen zur
Format-Optimierung von
Multimedia-Datenbanken
Diplomarbeit von Stefan Holland
im Studiengang Diplom-Wirtschaftsmathematik
an der Universitat Augsburg
Erstgutachter: Prof. Dr. Werner Kieling
Zweitgutachter: Prof. Dr. Bernhard Moller
Betreuer: Matthias Wagner
Augsburg, Juli 1999
Vorwort
Am Ende des 20. Jahrhunderts be
ndet sich die Gesellschaft im Umbruch von
der Industrie- zur Informationsgesellschaft. Zu dieser Entwicklung tragt das
World-Wide-Web (WWW), der weltweite Informationsdienst im Internet, mageblich bei. Firmen konnen sich im WWW prasentieren und so um Kunden werben, Versandhauser ermoglichen Home-Shopping, indem sie ganze Kataloge im
Netz bereitstellen, Forscher konnen Publikationen im Internet veroentlichen
und so einem breiten Leserkreis zur Verfugung stellen u.v.m.
Wesentlich fur die Prasentation im Internet ist eine u bersichtliche Darstellung
dieser Informationsut. Dies wird zum einen durch sogenannte Hyperlinks (Verweise auf andere Textstellen bzw. Dokumente) erreicht, so da eine u bersichtliche Gliederung das Lesen erleichtert. Zum anderen erlaubt der Einsatz multimedialer Hilfsmittel (Bilder, Audio- und Videodokumente) eine optisch und
akustisch sehr ansprechende Darstellung von Information. Man denke hier beispielsweise an einen Reiseveranstalter, der sein Angebot online zur Verfugung
stellt: Erst die Abbildung eines Reiseziels ermoglicht dem Kunden eine genaue
Vorstellung seines potentiellen Urlaubsorts.
Da die Benutzer unterschiedliche Browser, Viewer und Player zum Anzeigen
bzw. Abspielen von Multimediadokumenten verwenden, sollten diese in verschiedenen Formaten (z.B. GIF, JPG und Postscript bei Bildern, AUX und
WAV bei Audiodaten) verfugbar sein. Ebenso machen die Heterogenitat der verwendeten Netzwerkhardware (LAN, WAN, ISDN, Modem u.a.) und die damit
verbundenen unterschiedlichen Datenubertragungsraten auch wahlbare Qualitatsstufen sinnvoll, so da durch eine geringere Bildauosung bzw. Samplingrate auch bei niederen Transferraten die Ladezeit klein bleibt.
Wird nun ein bestimmtes Format in einer bestimmten Qualitat hau
g angefordert, sollten die Dokumente eventuell auch in diesem gespeichert werden und
nicht erst bei der Anfrage aus dem Original konvertiert werden. Hierbei mu allerdings genau zwischen Rechenersparnis und Festplattenbedarf abgewagt werden. W. Kieling, W. Kowarschick und G. Kostler haben in KKK97] einen
Algorithmus vorgestellt, der diesen Proze automatisiert, Peter Rieger hat eine
erste prototypische Implementierung vorgenommen (Rie97]).
In dieser Diplomarbeit wird zum Algorithmus aus KKK97] eine Variante mit
erheblich geringerer Komplexitat vorgestellt, die dafur allerdings bestimmte
Anforderungen an das Konvertierungstool stellt (siehe Kapitel 2). Auch werden
die Kostenfunktionen erweitert, so da Speicher- und Rechenaufwand moglichst
gut an die Realitat angepat werden konnen. Im Gegensatz zu Rie97] beruck-
ii
sichtigt hier die Implementierung zusatzlich zu den Formaten auch verschiedene
Qualitatsstufen.
Danksagungen
Ich bedanke mich bei Herrn Prof. Dr. W. Kieling und seinen Mitarbeitern
am Lehrstuhl fur Datenbanken und Informationssysteme fur die umfangreiche
fachliche Unterstutzung, die Bereitstellung neuester Hard- und Software und
die freundliche Beratung bei jeder Art von Problemen. Besonderer Dank gilt
meinem Betreuer Herrn Matthias Wagner, der mich in allen Belangen der Diplomarbeit hervorragend unterstutzte und dadurch mageblich zum Gelingen
beigetragen hat. Dank schulde ich auch Herrn Thorsten Ehm, der auf nahezu
alle Java-Fragen eine Antwort wute. Herzlich bedanke ich mich auch bei Frau
Gudrun Bauer, Herrn Stefan Fischer und Herrn Jurgen Vogel, die die Arbeit
korrektur gelesen haben. Schlielich sei auch meinen Kollegen im Datenbankraum fur die gute Zusammenarbeit gedankt.
Inhaltsverzeichnis
1. Einleitung
1
2. Optimierungsalgorithmen
7
1.1. Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.2. Die DB2-Extender . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3. Eine Beispielanwendung . . . . . . . . . . . . . . . . . . . . . . .
2.1.
2.2.
2.3.
2.4.
Der Basisalgorithmus . . . . . . . .
Modi
kation des Basisalgorithmus
Kostenfunktionen . . . . . . . . . .
Modi
kation der Kostenfunktionen
2.4.1. Speicherkosten . . . . . . .
2.4.2. Zugriskosten . . . . . . . .
2.5. Verbesserung der Laufzeit . . . . .
2.6. Aktualitat der Daten . . . . . . . .
3. Testszenarien
3.1.
3.2.
3.3.
3.4.
3.5.
3.6.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Vereinbarungen und Darstellung . . . . . . .
Die Benutzeroberache . . . . . . . . . . . . .
Kostenbewertung des Speicherbedarfs . . . .
Berechnung der Zugriskosten . . . . . . . . .
Reduzierung der Rechenzeit . . . . . . . . . .
Ausfuhrliche Beispiele . . . . . . . . . . . . .
3.6.1. Anfragen an eine Heraldik-Datenbank
3.6.2. Abfragen von Aktiencharts . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
1
2
4
7
9
11
12
13
13
14
15
17
17
19
20
23
25
27
27
35
Inhaltsverzeichnis
iv
4. Implementierung
42
4.1. Java und die Datenbankschnittstelle JDBC
4.2. Das Datenmodell . . . . . . . . . . . . . . .
4.3. Die Implementierung der Klassen . . . . . .
4.3.1. Die Klasse Attribut . . . . . . . . .
4.3.2. Die Klasse Optimization . . . . . . .
4.3.3. Die Klasse Opti . . . . . . . . . . . .
4.4. SQL-Fehler und Java-Ausnahmen . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
42
44
46
46
47
52
53
5. Kritische Anmerkungen zu den DB2-Extendern
55
6. Resumee und Ausblick
57
A. Shell-Skripte
59
B. Programmcode
63
A.1. Anlegen der Tabellen . . . . . . . . . . . . . . . . . . . . . . . . . 59
A.2. Einfugen der Bildinformation (gekurzt) . . . . . . . . . . . . . . 61
A.3. Einfugen der Bilder (gekurzt) . . . . . . . . . . . . . . . . . . . . 62
B.1. Die Webseite . . . . . . . . .
B.2. Das CGI-Programm . . . . .
B.3. Java und JDBC Programme .
B.3.1. Attribut.java . . . .
B.3.2. Optimization.java .
Literaturverzeichnis
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
63
65
68
69
70
91
1. Einleitung
1.1. Motivation
Seit ihrer Einfuhrung in den 60er Jahren haben sich Datenbanksysteme (DBS)
zu einer Querschnittstechnologie in den verschiedensten Anwendungsbereichen
etabliert, z.B.:
Personal- und Kundenverwaltung von U
Bestandserfassung im Bibliothekswesen
Fahrplanorganisation von Verkehrsbetri
♦
♦
♦
Dabei sind die Standarddatentypen (Integer, Char, u.a.) nicht fur alle Anwendungen ausreichend, beispielsweise konnte man in der Personaldatei eines
Mitarbeiters zusatzlich zu Name, Vorname, Postleitzahl und Wohnort auch Informationen in multimedialer Form speichern, wie z.B. Photo und Stimmprobe.
Auch Bibliotheken konnten zusatzlich zu Titel, Autor und Verlag auch Bilder
von Verfasser und Buchumschlag speichern.
Im SQL92-Standard steht dafur der Datentyp Blob zur Verfugung, der Multimediadokumente mit 2 Gigabyte Maximalgroe in binarer Form aufnehmen
kann. Die moglichen Operationen sind aber leider recht durftig:
♦
ugen, Loschen und A ndern eines Blobs
♦
♦
ange eines Blobs
♦
Einf
Test auf NULL
Ausgabe der L
Selektion eines Blobs, bei Bedarf mit A
Fur Multimediadokumente waren aber zusatzliche Informationen wunschenswert, wie z.B.:
♦
♦
ange einer Audio- oder Videosequenz
osung (Bilder)das verwendete Format und die verwen
die L
1.2 Die DB2-Extender
2
Insbesondere bei Bildern waren zusatzlich Formatkonvertierungen und Skalierungen wunschenswert, um die Dokumente moglichst vielseitig verwenden zu
konnen (GIF- und JPG-Bilder mittlerer Qualitat fur Prasentationen im Internet, PS- und EPS-Bilder hoher Auosung zum Drucken, PCX und BMP zum
Weiterverarbeiten unter Microsoft Windows u.v.m.).
Das Tool DB2-Extender1 von IBM erlaubt dies fur DB21 -Datenbanken und
ermoglicht eine Ad-hoc-Formatkonvertierung und -Skalierung bei einer entsprechenden Anfrage. Falls nun ein bestimmtes Format in einer bestimmten Auflosung hau
g angefragt wird, ist es eventuell sinnvoll, die Bilder auch in diesem
Format mit der entsprechenden Auosung physikalisch zu speichern, um den
Rechner durch weniger Konvertierungen zu entlasten. Andererseits steht der
Rechenersparnis ein erhohter Festplattenbedarf gegenuber, so da eine zusatzliche physikalische Speicherung der Bilder stets genau abgewogen werden sollte.
Im Kapitel 2 werden Algorithmen vorgestellt, die diesen Vorgang automatisieren. Die Testszenarien im Kapitel 3 veranschaulichen den Nutzen der Optimierung und beschreiben die Auswirkungen der einzelnen Parameter. Kapitel 4
stellt die Programmiersprache Java mit der Datenbankschnittstelle JDBC und
die wesentlichen Aspekte der Implementierung vor. Im Kapitel 5 wird kurz auf
typische Probleme beim Einsatz der DB2-Extender eingegangen. Resumee und
Ausblick im Kapitel 6 beschlieen die Diplomarbeit.
1.2. Die DB2-Extender
In DB2-Datenbanken kann der Benutzer die vorde
nierten Datentypen (Char,
Integer, Blob, ...) und Funktionen (count, max, avg, ...) um sog. User De
ned Types (UDTs) und User De
ned Functions (UDFs) erweitern. Die DB2Extender stellen solche UDTs und UDFs zur Verwaltung von Multimediadatenbanken zur Verfugung. Die Datentypen heien
♦
DB2Image
♦
DB2Audio
♦
DB2Video
und werden als Varchar(250) de
niert. Sie beinhalten naturlich nicht die eigentlichen Dokumente, sondern lediglich Verweise auf von den DB2-Extendern
intern angelegte Tabellen (falls die Dokumente als Blobs gespeichert sind) oder
auf Dateien (falls die Dokumente im Filesystem abgelegt sind).
Eine Vielzahl von Funktionen ermoglicht eine umfangreiche Bearbeitung von
Multimediadokumenten. Die wichtigsten UDFs fur Bilder lauten:
1
DB2r und DB2r Extenders sind eingetragene Warenzeichen der International Business
Machines Corporation (IBM)
1.2 Die DB2-Extender
Funktion
content
db2image
format
size
3
Beschreibung
liefert das Bild als Blob oder Datei zuruck,
einschlielich Formatkonvertierung und Skalierung
speichert, konvertiert und skaliert Bilder
gibt das Format zuruck
berechnet die Bildgroe in Byte
Zusatzlich gibt es noch etliche Funktionen zur bildinhaltlichen Recherche, auf
die hier nicht naher eingegangen wird.
Folgende Tabelle stellt die von den DB2-Extendern unterstutzten Bildformate
vor:
Format
BMP
EPS
EP2
GIF
IMG
IPS
JPG
PCX
PGM
PS
PSC
PS2
TIF
YUV
Beschreibung
OS/2 - Microsoft Windows bitmap
verkapseltes Postscript
verkapseltes Postscript, Level 2 (Farbe)
Compuserve GIF89a (einschlielich animierte GIFs) und GIF87
IOCA image
Brooktrout FAX Dateien
JPEG (3)
PC paint Dateien
Portable grey map
Postscript
komprimiertes Postscript
Postscript, Level 2 (Farbe)
TIFF 5.0
digitales Video fur YUV
Fur Konvertierungen zwischen diesen Formaten gilt:
1. Die Postscript-Formate (EPS, EP2, PS, PSC, PS2) konnen nicht Quellformat einer Konvertierung sein.
2. Ansonsten sind beliebige Formatumwandlungen moglich.
Beispiel
nicht erlaubt
erlaubt
GIF ! BMP TIF ! PS PS ! TIF
GIF ! JPG TIF ! PCX PS ! EPS
Bei einer Formatkonvertierung ist auch gleichzeitig eine Skalierung der Bilder
moglich.
Die DB2-Extender stellen zusatzlich das nicht sehr gangige Format IM (Beschreibung lt. Dokumentation in Ext]: PS/2 Audio Video Connection (AVC))
1.3 Eine Beispielanwendung
4
zur Verfugung. Bilder in diesem Format konnen gelesen werden, Konvertierungen zu IM sind aber nicht gestattet. Deshalb wird dieses Format in dieser
Arbeit nicht verwendet.
Weitere Einschrankungen und Probleme bei der Verwendung der DB2-Extender
werden im Kapitel 5 beschrieben.
1.3. Eine Beispielanwendung
Die Internet-Seite2 in Abbildung 1.1 zeigt beispielhaft die Verwendung der DB2Extender.
Abbildung 1.1.: Bildauswahl
Die hier aufgelisteten Bildbeschreibungen werden aus einer Tabelle einer DB22
http://heron.informatik.uni-augsburg.de/db2www-bin/db2www/da1 net/input
1.3 Eine Beispielanwendung
5
Datenbank gelesen. Nach dem Anklicken des gewunschten Bildes kann der Benutzer Format und Skalierung auswahlen.
Abbildung 1.2.: Auswahl von Format und Skalierung
Ein Skalierungsfaktor von 100% gibt das Bild in seiner ursprunglichen Groe
zuruck, ansonsten wird es entsprechend der Prozentangabe verkleinert. Man
beachte, da dadurch auch die Auosung gewahlt wird, denn wird das Originalbild auf z.B. 50% skaliert, so fallt in jeder Dimension die Halfte der Punkte
weg. Wird dieses Bild danach manuell auf die Originalgroe vergroert, so hat
es im Vergleich zum ursprunglichen Bild nur noch die halbe Auosung. Aus diesem Grund werden in dieser Arbeit die Begrie "Qualitat\, "Skalierung\ und
"Auosung\ synonym verwendet.
Ein Klick auf den "Submit\-Button schickt die Anfrage ab. Der Web-Server
leitet sie an den Datenbankserver weiter. Da in dieser Anwendung die Bilder
im GIF-Format in der Datenbank vorliegen, kann das gewunschte Bild ohne
1.3 Eine Beispielanwendung
6
Konvertierung zuruckgeliefert werden.
Abbildung 1.3.: Anfrageergebnis ohne Konvertierung
Wahlt der Benutzer dagegen das JPG-Format und eine 75%-Skalierung, so wird
es aus dem dazugehorenden GIF-Bild konvertiert und gleichzeitig verkleinert.
Abbildung 1.4.: Anfrageergebnis mit Konvertierung
Fur den Benutzer ist es also vollkommen transparent, ob das angefragte Bild
tatsachlich im gewunschten Format vorliegt oder erst konvertiert werden mu.
Die einzelnen Anfragen werden in einer Tabelle registriert und ermoglichen
so dem Administrator eine Optimierung der Multimediadatenbank: Aufgrund
dieser statistischen Daten kann er entscheiden, welche Formate bzw. Qualitatsstufen zukunftig in der Datenbank physikalisch gespeichert werden und welche
aus bestehenden Bildern konvertiert werden.
Dazu werden im nachsten Abschnitt geeignete Algorithmen entwickelt.
2. Optimierungsalgorithmen
Dieses Kapitel stellt Algorithmen vor, die abhangig vom Anfragepro
l die Menge der zu speichernden und der zu konvertierenden Formate bestimmen. Der
zunachst vorgestellte Basisalgorithmus aus KKK97] ist unabhangig von der
Menge der moglichen Konvertierungen anwendbar. Die schnellere Variante aus
Abschnitt 2.2 eignet sich fur den Fall, da alle Bilder zunachst in einem einzigen Referenzformat vorliegen und auch alle anderen unterstutzten Formate sich
daraus berechnen lassen. Die DB2-Extender erfullen diese Voraussetzungen fur
verschiedene Referenzformate (vgl. Abschnitt 1.2) und eignen sich damit fur
den 2. Algorithmus.
2.1. Der Basisalgorithmus
Zunachst werden die primar gespeicherten Bilder betrachtet.
Denition 2.1 (Referenzbilder, Referenzformat)
Die ursprunglich in der Datenbank vorliegenden Bilder heien Referenzbilder,
ihre Formate werden als Referenzformate bezeichnet.
Diese Bilder sollen nun nicht nur in verschiedenen Formaten, sondern auch in
mehreren Qualitatsstufen verfugbar sein.
Denition 2.2 (Attribut)
Ein Attribut A besteht aus einem Tupel (Format, Qualitatsstufe). Dabei wird
die Qualitat prozentual zur Grundauosung angegeben, die durch die Referenzbilder festgelegt ist.
A bezeichnet eine Menge von Attributen, Aphys ist die Menge der zu speichernden Attribute und Acomp sind die aus Aphys zu konvertierenden Attribute, wobei
Acomp = A n Aphys gilt.
Um die Notation zu vereinfachen werden Attribute stets mit TIF100 statt
(TIF, 100%), GIF50 statt (GIF, 50%) usw. bezeichnet.
Denition 2.3 (funktionale Abhangigkeit)
A sei ein Attribut, X eine Menge von Attributen und f eine Funktion. Dann
heit fC (A = f (X )) funktionale Abhangigkeit. Hierbei ist A Kopfattribut
und X sind Rumpfattribute von fC .
2.1 Der Basisalgorithmus
8
Falls nun f eine Konvertierungsfunktion ist, so kann das Attribut A damit aus
X berechnet werden. Verwendet man die DB2-Extender als Konvertierungstool,
so ist X stets einelementig (z.B. X = fB g fur ein Attribut B ). Die funktionale
Abhangigkeit lautet in diesem Fall fC (A = f (B )).
Denition 2.4 (funktionale Basis)
Sei F eine Menge funktionaler Abhangigkeiten. Dann heit Fcomp 2 F genau
dann funktionale Basis, wenn gilt:
1. Kein Attribut hangt von sich selbst funktional ab (weder direkt noch transitiv).
2. Jedes A 2 A ist hochstens Kopfattribut einer funktionalen Abhangigkeit
fC 2 Fcomp .
Hierbei verhindert 1., da ein Attribut zyklisch von sich selbst abhangt, und
sorgt 2. dafur, da die Berechnung von A 2 Acomp eindeutig ist.
Denition 2.5 (optimale funktionale Basis)
Sei cost eine Kostenfunktion. Eine funktionale Basis Fopt heit genau dann
optimal, wenn
cost(Fopt ) = minfcost(Fcomp)j Fcomp ist funktionale Basis g
Ziel der Optimierung ist es also, eine bzgl. einer Kostenfunktion beste funktionale Basis zu bestimmen. Daraus ergibt sich Acomp als Menge der Kopfattribute
von Fopt und damit Aphys = A n Acomp.
Algorithmus 2.1
Attributmenge A
Menge F der moglichen Konvertierungen
Kostenfunktion cost
Initialisierung: Fopt := min := cost()
FOR Fcomp F WHERE
Fcomp is functional base
DO
IF cost(Fcomp ) < min
THEN
min := cost(Fcomp)
Fopt := Fcomp
FI
OD
Fopt min
Ausgabe:
Eingabe:
Geeignete Kostenfunktionen werden im Abschnitt 2.3 vorgestellt. Eine detaillierte theoretische Betrachtung ndet sich in KKK97], eine Implementierung
dieser Optimierung erfolgt in Rie97].
2.2 Modikation des Basisalgorithmus
9
2.2. Modikation des Basisalgorithmus
Die DB2-Extender erlauben nahezu beliebige Konvertierungen zwischen den Attributen, d.h. bei n Attributen gibt es fast n2 funktionale Abhangigkeiten. Fur
diesen Fall hat obiger Algorithmus lt. KKK97] eine worst-case Komplexitat von
O(n2 (n + 1)n ). Der folgende Algorithmus ermoglicht eine Laufzeitverkurzung,
indem er nicht die Potenzmenge der funktionalen Abhangigkeiten, sondern die
der Attribute durchlauft.
Algorithmus 2.2
Attributmenge A
Kostenfunktion cost
Initialisierung: Aphys = A
Acomp = min = cost(Aphys Acomp)
FOR A~phys A
DO
A~comp = A n A~phys
IF cost(A~phys A~comp ) < min
THEN
Aphys = A~phys
Acomp = A~comp
min = cost(A~phys A~comp)
FI
OD
Ausgabe:
Aphys Acomp cost
Eingabe:
Dieser Algorithmus wahlt aus der Attributmenge A die zu speichernden Attribute direkt aus. Dabei wird ebenso wie im Algorithmus 2.1 eine Kostenfunktion
verwendet, auf die noch genauer eingegangen wird.
Damit dem Benutzer stets alle unterstutzten Formate zur Verfugung stehen,
werden folgende Voraussetzungen verlangt:
1. Alle Bilder liegen vor der ersten Optimierung in einem einheitlichen Referenzformat vor.
2. Samtliche zu unterstutzenden Attribute konnen aus diesem konvertiert
werden.
Der 1. Punkt ist keine groe Einschrankung, denn in vielen Fallen werden die
Bilder bereits im gleichen Format vorliegen (z.B. bei eingescannten Bildern).
Falls jedoch unterschiedliche Formate verwendet wurden, so konnen die Bilder
mit den DB2-Extendern leicht auf ein einheitliches Format konvertiert werden.
Die 100% Qualitatsstufe des Referenzformats sollte nicht in die Attributmenge
A der Optimierung aufgenommen werden, damit diese nie geloscht wird.
2.2 Modikation des Basisalgorithmus
10
Die Erfullbarkeit der 2. Voraussetzung hangt von der Machtigkeit des Konvertierungstools ab. Bei den DB2-Extendern sind folgende Referenzformate moglich
(vgl. Abschnitt 1.2):
BMP, GIF, IMG, IPS, JPG,PCX, PGM, TIF, YUV
Ebenso wie beim Basisalgorithmus mu auch hier gewahrleistet werden, da
fur jedes A 2 Acomp die Konvertierungsfunktion eindeutig ist. Fur die DB2Extender garantieren dies folgende Regeln fur die Wahl des Quellattributs der
Konvertierung:
1. Sei A ein Attribut, dessen Format weder EPS, EP2, PS, PSC noch PS2 ist.
Falls nun zu diesem A ein Attribut in Aphys existiert, das gleiches Format,
aber bessere Auosung hat, so wahle dieses. Gibt es davon mehrere, so
wahle dasjenige, dessen Auosung der von A am nachsten ist.
2. Ansonsten verwende das Referenzformat als Quellattribut.
Bilder in Postscript-Formaten konnen von den DB2-Extendern nicht skaliert
werden und mussen deshalb stets aus der Referenzbildern konvertiert werden,
sofern sie nicht in der Datenbank prasent sind.
Beispiel
Sei TIF das Referenzformat, GIF, JPG, PCX und PS die weiteren verfugbaren
Formate und die moglichen Qualitatsstufen 100%, 50% und 25%.
Eine Optimierung habe Aphys = fGIF100, GIF50, JPG50, PCX25, PS100g ergeben. Die Attribute werden dann gema dem Graphen aus Abbildung 2.1 erzeugt. Naturlich mussen nur an den durchgezogenen Pfeilen Konvertierungen
durchgefuhrt werden.
;
GIF100 ?
;
GIF100 ;
;
;
GIF50 GIF50 ?
;
?
JPG50 ;
GIF50 GIF25 ?
;
JPG50 ;
;
JPG50 ?
;
PCX25 PS100 ;
JPG25 ?
;
?
;
9
;
)
TIF100 ;
?
;
j
;
JPG100 PCX100 PCX50 PS50 q
;
PS25 Abbildung 2.1.: Beispiel zulassiger Konvertierungen
Komplexitat
;
PCX25 PS100 Ist n die Anzahl der Attribute in A, dann hat deren Potenzmenge die Machtigkeit 2n . Falls nun der Aufwand der Kostenberechnung quadratisch in n ist (siehe
Seite 12), so hat der Algorithmus eine Komplexitat von O(n2 2n ).
2.3 Kostenfunktionen
11
Folgende Tabelle vergleicht die Laufzeit beider Algorithmen, falls n Attribute
vorliegen und das Konvertierungs-Tool beliebige Konvertierungen zwischen den
Attributen erlaubt:
n
3
4
5
7
9
11
13
15
20
25
30
Algorithmus 2.1 Algorithmus 2.2
n2 (n + 1)n
n 2 2n
576
72
10000
256
194400
800
8
1:03 10
6272
8:10 1010
41472
8:99 1013
247808
1:34 1017
1384448
2:59 1020
7372800
29
1:11 10
4:19 108
38
1:48 10
2:10 1010
47
4:96 10
9:66 1011
2.3. Kostenfunktionen
Die Gute der Optimierung hangt entscheidend von der Wahl der Kostenfunktion
ab.
Denition 2.6 (Kostenfunktion)
cost(Aphys Acomp) := (1 ; z ) store cost(Aphys)
+z acc cost(Aphys Acomp)
Die Kosten setzen sich also aus Speicher- und Zugriskosten zusammen, wobei
z 2 0 1] ein Gewichtungsparameter ist.
Diese Parameterisierung der Kostenfunktion entspricht zwar dem Algorithmus
2.2, kann aber ebenso im Basisalgorithmus verwendet werden, da ja Fcomp die
Attributmenge in Acomp und Aphys zerlegt, so da
cost(Fcomp ) = cost(Aphys Acomp)
gilt.
Denition 2.7 (Speicherkosten)
P
store cost(Aphys) := cS A2Aphys avg size(A)
Die Speicherkosten sind also proportional zur Summe der durchschnittlichen
Attributgroen.
2.4 Modikation der Kostenfunktionen
12
Denition 2.8 (Zugriskosten)
P
acc cost(Aphys Acomp ) := A2A avg acc(A) acc cost(A)
wobei avg acc(A) die durchschnittliche Zugrisrate ist.
Die Zugriskosten summieren sich also aus den attributbezogenen Zugriskosten, gewichtet mit der durchschnittlichen Zugrisrate.
Denition 2.9 (Zugriskosten fur ein Attribut)
acc cost(A) := cA avg size(A)
falls A 2 Aphys
comp cost(B A) + acc cost(B ) falls A 2 Acomp
wobei comp cost(B A) die Rechenkosten fur die Konvertierung des Attributs A
aus dem Attribut B 2 Aphysist.
Fur die Wahl des Quellattributs B konnen beispielsweise die auf Seite 10 vorgestellten Regeln verwendet werden. Im Algorithmus 2.1 wird die verwendete
Konvertierung und damit das Quellattribut durch die Menge Fcomp festgelegt.
Denition 2.10 (Konvertierungskosten)
comp cost(B A) := cC avg conv time(B A)
wobei cC ein Skalierungsparameter und avg conv time(B A) die durchschnittliche Dauer fur eine Konvertierung B ! A ist.
Falls die durchschnittliche Rechenzeit fur eine Formatumwandlung nicht bekannt ist, sollte sie aus statistischen Daten ermittelt werden.
Komplexitat der Kostenfunktionen
Die Berechnungen gema De
nitionen 2.6 - 2.8 und 2.10 haben hochstens linearen Aufwand (bzgl. der Anzahl der Attribute), sofern die benotigten statistischen Daten bereits bekannt sind. Bei den Zugriskosten fur ein Attribut
mu fur jedes A 2 Acomp das entsprechende Quellattribut gesucht werden.
Dazu durchlauft Algorithmus 2.1 die Menge Fcomp und Algorithmus 2.2 die
Menge Aphys, so da sich der Rechenaufwand fur die Kosten durch O(n jFj)
bzw. O(n2 ) nach oben abschatzen lat. Naturlich kann man die Ermittlung des
Quellattributs auch ezienter implementieren (z.B. durch Verwendung einer
Hashtabelle), allerdings rechtfertigt die schnellere Suche nicht unbedingt den
zusatzlichen Verwaltungsaufwand (v.a. bei kleinen Mengen).
2.4. Modikation der Kostenfunktionen
In diesem Abschnitt werden verbesserte Kostenfunktionen vorgestellt, die durch
zusatzliche Parameter (de-)aktiviert und eingestellt werden konnen.
2.4 Modikation der Kostenfunktionen
13
2.4.1. Speicherkosten
Die Kosten fur die persistente Speicherung der Bilder entstehen durch die Belegung von Speicherplatz auf Datentragern. De
nition 2.7 erfat dies nur unzureichend, da hier nur die durchschnittliche Bildgroe relevant ist. Besser ware
es, hier den tatsachlichen Speicherbedarf zu berucksichtigen.
Denition 2.11 (Speicherkosten (2))
P
store cost(Aphys) := cS A2Aphys number of images avg size(A)
wobei number of images die Anzahl der Bilder ist.
Dieser Ansatz modelliert also die Speicherkosten als proportional zu dem belegten Speicherplatz.
Da die Kosten moglicherweise sprunghaft beim Vergroern eines Tablespace
oder beim Kauf eines neuen Datentragers anfallen, konnen sie durch eine auf
den Speicherbedarf angewendeten Treppenfunktion F berechnet werden.
Denition 2.12 (Speicherkosten (3))
P
store cost(Aphys) := F A2Aphys number of images avg size(A)
wobei F eine geeignete Treppenfunktion ist.
Beispiel
Bei Verwendung von 3 Festplatten, wobei die erste 500 MB Kapazitat hat und
die Kosten 150 betragen, die zweite gleiche Kapazitat hat jedoch nur 100 kostet
und die dritte eine 1-GB-Platte zu 150 ist, so konnte die Treppenfunktion F
beispielsweise folgende Form habe:
8
x = 0
>
< 0150 falls
falls
0
<
500
F (x) = > 250 falls 500 < xx 1000
: 400 falls 1000 < x 2000
wobei x der tatsachliche Speicherbedarf in MB ist.
2.4.2. Zugriskosten
Gema De
nition 2.8 werden die Kosten fur ein Attribut mit der durchschnittlichen Zugrisrate gewichtet. Dies bedeutet aber, da die Anfragepro
le
Anfrageprol 1
Attribut Anzahl der Anfragen
GIF100
1
JPG100
2
Anfrageprol 2
Attribut Anzahl der Anfragen
GIF100
100
JPG100
200
2.5 Verbesserung der Laufzeit
14
die gleichen Zugriskosten haben konnen. Ist dies nicht erwunscht, so kann als
Gewicht die tatsachliche Zahl der Anfragen fur ein Attribut verwendet werden.
Denition 2.13 (Zugriskosten (2))
P
acc cost(Aphys Acomp) := A2A total acc(A) acc cost(A)
wobei total acc(A) die Anzahl der Anfragen fur das Attribut A ist.
Dabei ist allerdings zu beachten, da dadurch die Zugriskosten sehr gro werden konnen, so da u.U. eine Anpassung der anderen Parameter (v.a. z , vgl.
De
nition 2.6) notwendig wird.
2.5. Verbesserung der Laufzeit
Algorithmus 2.2 hat exponentielle Komplexitat bezuglich der Anzahl der Attribute. Aus diesem Grund sollte der Suchraum klein gehalten werden, indem
beispielsweise nur die Attribute in die Optimierung eingehen, die tatsachlich angefragt worden sind. Dies kann noch weiter verfeinert werden, indem davon nur
die berucksichtigt werden, die mehr als p-mal angefordert wurden. Aus diesen
wahlt dann der Algorithmus die zu speichernden Attribute aus.
Dieses Vorgehen ermoglicht es damit auch, dem Benutzer eine groere Anzahl
an Qualitatsstufen anzubieten, ohne da sich die Laufzeit des Algorithmus wesentlich verschlechtert.
Beispiel
Gegeben sei folgendes Anfragepro
l:
Attribut Anzahl der Anfragen
GIF100
80
GIF75
3
GIF50
75
GIF25
7
PS100
110
PS50
12
PCX100
40
PCX75
8
JPG100
60
JPG50
2
Dann vergleicht folgende Tabelle die Laufzeiten bei Variation des oben beschriebenen Parameters p:
2.6 Aktualitat der Daten
15
p ausge
lterte Attribute
1
2
3
5
10
15
JPG50
JPG50, GIF75
JPG50, GIF75, GIF25, PCX75
JPG50, GIF75, GIF25, PCX75, PS50
Anzahl n
relevanter
Attribute
10
10
9
8
6
5
O(n) = n2 2n
102400
102400
41472
16384
2304
800
Dies ermoglicht also eine Aufteilung in "wichtige\ und "unwichtige\ Attribute.
2.6. Aktualitat der Daten
Abhangig vom aktuellen Query-Pro
l liefert der Algorithmus 2.2 die Menge
der zu speichernden Attribute als Ergebnis. Falls nun bis zur nachsten Optimierung keine Anfragen an ein Attribut dieser Menge gestellt werden, schlagt
der Algorithmus u.U. vor, dieses Attribut zu loschen. Dieses Verhalten kann
zu einem unnotig hau
gen Speichern und Loschen von Attributen fuhren. Um
dies zu verhindern, sollten auch altere Querys in die Optimierung eingehen. Um
andererseits aber auch die Aktualitat weiterhin gewahrleisten zu konnen, sollte
jede Anfrage nur fur eine begrenzte Anzahl von Optimierungen relevant sein.
In der Implementierung fuhrt dies zur Einfuhrung eines neuen Parameters q,
der die Anzahl der Optimierungen angibt, fur die im Query-Pro
l registrierte
Anfragen verwendet werden sollen.
Beispiel
Folgendes Szenario (Referenzformat z.B. TIF, 100 Bilder) ist denkbar, falls jede
Anfrage fur nur eine Optimierung verwendet wird (q = 1):
Lauf
1
2
3
4
5
6
7
8
Anfragepro
l
50 GIF100
50 JPG100
50 GIF100
50 JPG100
50 GIF100
50 JPG100
50 GIF100
50 JPG100
Aphys
GIF100
JPG100
GIF100
JPG100
GIF100
JPG100
GIF100
JPG100
Werden die Anfragen fur zwei Optimierungslaufe verwendet (q = 2), so ist
folgender Ablauf moglich:
2.6 Aktualitat der Daten
Lauf
1
2
3
4
5
6
7
8
Anfragepro
l
50 GIF100
50 JPG100
50 GIF100
50 JPG100
50 GIF100
50 JPG100
50 GIF100
50 JPG100
16
Aphys
GIF100
GIF100, JPG100
GIF100, JPG100
GIF100, JPG100
GIF100, JPG100
GIF100, JPG100
GIF100, JPG100
GIF100, JPG100
Nur nach den Laufen 1 und 2 erfolgen A nderungen in Aphys, wahrend im obigen
Fall nach jedem Lauf 100 Bilder konvertiert und 100 Bilder geloscht werden
mussen.
Eine ausfuhrliche Analyse von Testlaufen erfolgt im nachsten Kapitel.
3. Testszenarien
Im Kapitel 2 wurden Algorithmen zur Formatoptimierung vorgestellt, die nun
an Beispielen getestet und analysiert werden sollen. Dabei wird insbesondere
auf Praxisbezug groen Wert gelegt und gezeigt, wie die bereits vorgestellten
Parameter mit physikalischen Groen wie Festplattengroe und -kosten, Datentransferrate u.a. zusammenhangen.
3.1. Vereinbarungen und Darstellung
Denition 3.1 (Lauf, Szenario)
Ein (Optimierungs-)Lauf besteht aus einer Menge von Anfragen gefolgt von
einer Optimierung, ein Szenario besteht aus mehreren Laufen.
Um auch komplexe Szenarien ubersichtlich darstellen und analysieren zu konnen,
werden nicht alle moglichen Formate verwendet.
♦
♦
Als Anfrageformate werden nur BMP, G
eingesetzt.
oglichen Skalierungen sind 100%, 75%, 50% und 25%. Die m
Da die Testszenarien eine Fulle von Datenmaterial liefern, soll deren Auswertung i.a. graphisch (vgl. Abbildung 3.1) erfolgen. Dafur werden folgende Vereinbarungen getroen:
♦
♦
♦
♦
♦
Das Anfragepro
l wird durch ein gestap
wobei die Hohe eines Balkens die Gesamtanzahl der Anfragen eines Laufs
wiedergibt.
Kosten, Rechenzeiten u.a. werden durch
derder
Anfraprim
aren y-Achse (in Graphiken links) kann die ZahlAn
gen abgelesen werden, rechts an der sekundaren y-Achse die Kosten oder
Rechenzeiten.
Die Einheiten werden soweit m
oglich mit angegeben.
Die x-Achse ist mit der Nummer der
aufe und/oder den physikalisch
gespeicherten Attributen beschriftet.
3.1 Vereinbarungen und Darstellung
18
100000
40
35
10000
30
25
number
of requests
20
1000
computing_time
(log scale, ms)
100
15
10
10
5
1
0
1
2
3
4
5
6
7
8
9
10
run
11
12
13
14
15
16
17
18
19
BMP100
BMP75
BMP50
BMP25
GIF100
GIF75
GIF50
GIF25
JPG100
JPG75
JPG50
JPG25
PCX100
PCX75
PCX50
PCX25
computing_time (q=100)
computing_time (q=1)
Abbildung 3.1.: Beispielgraphik
Die Legendenbeschriftungen stammen direkt aus der Datenbank und werden in
der folgenden Tabelle erlautert:
Beschriftung
number of requests
A phys
cost
store cost
acc cost
pre opt
post opt
no opt
save all
computing time
total time
Bedeutung
Anzahl der Anfragen
gespeicherte Attribute
Gesamtkosten
Speicherkosten
Zugriskosten
vor der Optimierung
nach der Optimierung
ohne Optimierung
Speicherung aller angefragten Attribute
Rechenzeit der Optimierung
Gesamtzeit einschl. Aktualisierung der Datenbank
Wie aus Abbildung 3.2 ersichtlich, werden verschiedene Formate durch Farben unterschieden. Den Skalierungsfaktoren entsprechen unterschiedliche Helligkeitsstufen.
3.2 Die Benutzeroberache
19
BMP100
BMP75
BMP50
BMP25
GIF100
GIF75
GIF50
GIF25
IPS50
IPS25
1,2
1
0,8
0,6
0,4
0,2
0
IPS100
IPS75
JPG100
JPG75
JPG50
JPG25
PCX100
PCX75
PCX50
PCX25
PS100
PS75
PS50
PS25
TIF100
TIF75
TIF50
TIF25
hallo
1
Abbildung 3.2.: Legende der Attribute
3.2. Die Benutzerober
ache
Das Programm Scenery.java (zum Ausfuhren wird java Scenery standard
eingegeben) stellt eine graphische Oberache zur Verfugung, die die einfache
Eingabe der Parameter und des Anfragepro
ls ermoglicht.
Fur jedes Szenario gibt man die Anzahl der Bilder in der Datenbank, das Referenzformat und die durchschnittliche Bildgroe ein. Ebenso werden die im Kapitel 2 vorgestellten Parameter z, c_s, c_a, c_c, p und q eingestellt. Wird der
Schalter use_total_store aktiviert, so verwenden die Speicherkosten den Gesamtspeicherbedarf aller Attribute, ansonsten nur die durchschnittlichen Bildgroen der Attribute (vgl. De
nitionen 2.7 und 2.11). Mit use_stepfunction
werden das Feld c_s deaktiviert und die Eingabe von Plattengroen und -kosten
ermoglicht (De
nition 2.12). U ber use_total_access entscheidet man schlielich zwischen durchschnittlicher Zugrisrate und Gesamtzugriszahl (De
nitionen 2.8 und 2.13).
Im ersten Textfeld wird das Anfragepro
l wie im Beispiel (Abbildung 3.3) eingegeben. Dabei wird an jedem senkrechten Strich (|) eine Optimierung durchgefuhrt.
Das untere Textfeld gibt Informationen uber den Verlauf des Szenarios aus.
Am Ende ndet sich hier fur jede Optimierung eine Auistung der Kosten, die
Menge der physikalisch gespeicherten Attribute und die benotigte Rechenzeit.
Dies kann ebenso wie die Eingabe gespeichert werden. Auerdem werden diese
Daten zur spateren Auswertung auch in der Datenbank erfat.
3.3 Kostenbewertung des Speicherbedarfs
20
Das Programm kann auch mit java Scenery inputfile outputfile gestartet werden. Dabei werden aus inputfile die Eingabedaten (Parameter und
Anfragepro
l) gelesen und das Ergebnis des Szenarios in die Datei outputfile
geschrieben. Dies ermoglicht den Ablauf von Szenarien ohne Benutzerinteraktion, so da sie z.B. auch nachts ausgefuhrt werden konnen.
Abbildung 3.3 zeigt die Oberache wahrend eines Szenarios.
Abbildung 3.3.: Oberache fur die Testszenarien
3.3. Kostenbewertung des Speicherbedarfs
Im Abschnitt 2.3 und 2.4 wurden fur Speicherkosten verschiedene De
nitionen
vorgestellt, deren praktische Relevanz nun erlautert werden soll.
Gema De
nition 2.7 ist fur die Speicherkosten lediglich die durchschnittliche
Attributgroe ausschlaggebend, d.h. die Anzahl der Bilder in der Datenbank ist
irrelevant. Zur Veranschaulichung werden drei Szenarien getestet, die bis auf die
Zahl der Bilder vollkommen identisch sind (Abbildung 3.4). Dabei besteht jede
Datenbank primar aus 10, 100 oder 200 Bildern im TIF-Format, wobei jedes
3.3 Kostenbewertung des Speicherbedarfs
21
Bild etwa 100 KB gro ist. Als Ergebnis der Optimierungen werden in jedem
Szenario die Bilder auch im Attribut TIF50 gespeichert.
12
140
10
120
100
8
80
number 6
of requests
4
store_cost
60
40
2
20
0
0
TIF50 TIF50 TIF50 TIF50 TIF50 TIF50 TIF50 TIF50 TIF50 TIF50
A_phys
TIF50
store_cost (10 pictures)
store_cost (100 pictures)
store_cost (200 pictures)
Abbildung 3.4.: Speicherkosten verwenden die durchschnittliche Attributgroe
Die Kosten zum Speichern des Referenzformats werden nicht berucksichtigt, da
sie stets gleich sind und somit als Konstante die Optimierung nicht beeinussen. Die durchschnittliche Attributgroe der TIF50-Bilder betragt 28074 Byte,
so da sich mit c_s=0.005 Speicherkosten von etwa 140 ergeben. Dies ist unabhangig von der Anzahl der Bilder und damit unabhangig vom tatsachlich
belegten Speicherplatz.
Dieses Problem kann gelost werden, indem man den Parameter c_s erhoht,
falls mehr Bilder in der Datenbank sind. Trotzdem bleibt die Wahl von c_s
ziemlich willkurlich, insbesondere kann nicht gewahrleistet werden, da die errechneten Speicherkosten den tatsachlichen Speicherbedarf bzw. die Kosten fur
die Datentrager wiedergeben.
Als mogliche Verbesserung kann man den Schalter use_total_store aktivieren, so da sich die Speicherkosten gema De
nition 2.11 als Produkt aus c_s
und Gesamtspeicherbedarf (in Byte) zusammensetzen. Damit konnen die DaPF =
tentragerkosten direkt berucksichtigt werden: Ein Medienpreis von 10 MB
1
PF (z.B. SCSI-Festplatten) ergibt c_s=0.00001. Damit werden die Spei100000 Byte
cherkosten in Pfennig angegeben, andere Einheiten erfordern eine entsprechende
A nderung von c_s (z.B. DM: c_s=0.0000001, Euro: c_s=0.000000511).
Ein Beispiel be
ndet sich unten (Abbildung 3.5). Die Szenarien sind identisch
3.3 Kostenbewertung des Speicherbedarfs
22
mit den vorigen, nur da use_total_store aktiviert und c_s=0.00001 gewahlt
PF werden dann die Speicherkosten in
wird. Bei einem Medienpreis von 10 MB
Pfennig angegeben.
12
60
10
50
8
number
of requests
6
40
4
20
2
10
store_cost
30
0
0
TIF50
TIF50
TIF50
TIF50
TIF50
TIF50
TIF50
TIF50
TIF50
TIF50
A_phys
TIF50
store_cost (10 pictures)
store_cost (100 pictures)
store_cost (200 pictures)
Abbildung 3.5.: Speicherkosten verwenden die tatsachliche Attributgroe
Hier erkennt man deutlich, da die Speicherkosten direkt von der Anzahl der Bilder abhangen und den tatsachlichen Datentragerkosten entsprechen: 200 TIF50Bilder brauchen 200 28074 = 5614800 Byte und damit betragen die Kosten
0:00001 5614800 = 56:148 Pfennig. Da hier die Bilder recht klein sind (ca. 28
KB), sind naturlich auch die Speicherkosten gering.
In der Praxis ist auch denkbar, da sich die Kosten sprunghaft verandern, beispielsweise beim Vergroern eines Tablespace oder beim Kauf und Einbau einer
neuen Festplatte. Dies kann man modellieren, indem man auf den Speicherbedarf eine Treppenfunktion F anwendet. Fur das Beispiel in Abbildung 3.6 wird
F folgendermaen gewahlt:
8
<0
F = : 100
220
Dabei wird x in MB eingegeben.
falls
x = 0
falls 0 < x 10
falls 10 < x 25
3.4 Berechnung der Zugriskosten
23
In der Oberache wird fur diesen Fall use_stepfunction aktiviert, wodurch das
c_s-Feld aus- und die Felder hd_size und hd_cost eingeschaltet werden. Obige
Treppenfunktion wird durch hd_size=10,15 und hd_cost=100,120 eingegeben. Bei einem Speicherbedarf groer als 25 MB wird durch eine oder mehrere
15-MB-Blocke mit Kosten zu 120 interpoliert. Das etwas komplexere Beispiel
aus Abbildung 3.6 zeigt den moglichen Verlauf der Speicherkosten.
45
40
200
35
30
150
25
number
of requests
20
store_cost
100
15
10
50
5
0
0
GIF100 GIF100 GIF100
GIF75 GIF75 GIF75
GIF50 GIF50
GIF25
GIF100
GIF75
GIF50
GIF25
A_phys
GIF100 GIF100 GIF100 GIF75 GIF50 GIF25 PCX100 PCX50 PCX50 PCX25 JPG100 JPG75 JPG50 JPG25
GIF75 GIF75 GIF75 GIF50 GIF25 PCX100 PCX75 PCX25 PCX25 JPG100 JPG75 JPG50 JPG25 BMP100
GIF50 GIF50 GIF50 GIF25 PCX100 PCX75 PCX50 JPG100 JPG100 JPG75 JPG50 JPG25 BMP100 BMP75
GIF25 GIF25 GIF25 PCX100 PCX75 PCX50 PCX25 JPG75 JPG75 JPG50 JPG25 BMP100 BMP75 BMP50
PCX100 PCX100 PCX100 PCX75 PCX50 PCX25 JPG100 JPG50 JPG50 JPG25 BMP100 BMP75 BMP50 BMP25
PCX75 PCX75 PCX75 PCX50 PCX25 JPG100 JPG75 JPG25 JPG25 BMP100 BMP75 BMP50 BMP25
BMP100 BMP75 BMP50 BMP25
PCX50 PCX50 PCX25 JPG100 JPG75 JPG50
BMP75 BMP50 BMP25
PCX25 JPG100 JPG75 JPG50 JPG25
BMP100
BMP75
BMP50
BMP25
GIF100
GIF75
GIF50
GIF25
JPG100
JPG75
JPG50
JPG25
PCX100
PCX75
PCX50
PCX25
store_cost
Abbildung 3.6.: Speicherkosten als Treppenfunktion
Wie in den vorigen Beispielen besteht die Datenbank primar aus 100 TIFBildern zu je 100 KB Groe. Im ersten Lauf wird kein Attribut zusatzlich gespeichert, in den folgenden vier und im dreizehnten Lauf wird nur die 10-MBPlatte gebraucht, andernfalls werden soviele Attribute gespeichert, da dafur
mehr als 10 MB benotigt werden.
3.4. Berechnung der Zugriskosten
Zunachst werden fur jedes Attribut einzeln die Zugriskosten berechnet. Diese hangen fur physikalisch gespeicherte Attribute von der durchschnittlichen
Groe und von der U bertragungsgeschwindigkeit des Datentragers (bei lokalem Zugri) oder des Netzwerks ab. Die Transfergeschwindigkeit kann mit dem
3.4 Berechnung der Zugriskosten
24
Parameter c_a (vgl. De
nition 2.9) berucksichtigt werden: U bertragt beispielsB
weise die Festplatte die Daten mit 20 MB
s = 20000 ms , so kann c_a=0.00005
gewahlt werden, da die durchschnittliche Bildgroe in Byte errechnet wird. Die
Zugriskosten sind dann in Millisekunden angegeben.
Mu das Attribut jedoch erst konvertiert werden, dann summieren sich die Kosten (gema De
nition 2.9) aus den Zugriskosten fur das Quellformat und der
Konvertierungsdauer. Letztere wird aus statistischen Daten ermittelt und ist in
Millisekunden angegeben. Fur obiges c_a kann dann der Skalierungsparameter
c_c=1 gew
ahlt werden. Sollen die Zugriskosten in anderen Einheiten berechnet werden (z.B. Sekunden), so sind sowohl c_a als auch c_c entsprechend zu
verandern.
Die Gesamtzugriskosten ergeben sich dann aus der Summe der Zugriskosten
fur die Attribute, jeweils gewichtet mit der durchschnittlichen Zugrisrate (vgl.
De
nition 2.8). Dies kann sinnvoll sein, falls es nicht auf die tatsachliche Zahl
der Anfragen pro Attribut ankommt. Andernfalls ware es besser, als Gewicht
nicht die Zugrisrate, sondern die tatsachliche Zahl der Anfragen herzunehmen
(vgl. De
nition 2.13).
70
160
60
140
120
50
100
acc_cost
80
number 40
of requests
30
60
20
40
10
20
0
0
TIF50 TIF50 TIF50 TIF50 TIF50 TIF50 TIF50 TIF50 TIF50
TIF75 TIF75 TIF75 TIF75 TIF75 TIF75 TIF75 TIF75 TIF75
A_phys
TIF50
TIF75
acc_cost post_opt (total acc)
acc_cost post_opt (avg acc)
Abbildung 3.7.: Durchschnittliche Zugrisrate vs. absolute Zugriszahl
Dieses Vorgehen liefert insbesondere dann gute Ergebnisse, wenn c_a und c_c
gema obigen Vorschlagen gewahlt werden. Dann geben namlich die Gesamtzugriskosten genau die Summe der Ladezeiten aller Anfragen wieder (beispielsweise in Millisekunden).
In der Graphik (Abbildung 3.7) wurde c_a=0.00005 und c_c=1 gewahlt. Deut-
3.5 Reduzierung der Rechenzeit
25
lich ist zu erkennen, da bei Verwendung der durchschnittlichen Zugrisraten
(dunne Linie) die Kosten unabhangig von der tatsachlichen Zugriszahl sind,
wahrend im zweiten Fall die Kosten entsprechend der Anfragezahl steigen. Auerdem konnen die Kosten dann direkt als Zeit (in Millisekunden) fur die Dauer
aller Anfragen interpretiert werden (falls die Transferrate 20 MB
s betragt).
3.5. Reduzierung der Rechenzeit
Werden zu den verschiedenen Formaten auch etliche Qualitatsstufen zur Verfugung gestellt, so gehen u U. sehr viele Attribute in die Optimierung ein. Da
der Algorithmus aber exponentielle Laufzeit bzgl. der Zahl der Attribute hat,
sollten vielleicht nur die Attribute relevant sein, die mehr als p-mal angefragt
worden sind. Wird p=1 gesetzt, so gehen alle angefragten Attribute in die Optimierung ein, fur beispielsweise p=5 nur die, die 5 mal oder ofter verlangt
wurden. Dadurch kann erheblich Rechenzeit eingespart werden, wie Abbildung
3.8 verdeutlicht.
1000
40
35
30
100
25
number
of requests
20
computing_time
(ms, log scale)
15
10
10
5
1
0
1
2
3
4
BMP100
GIF100
PCX100
TIF50
computing_time (p=5)
5
6
7
run
BMP75
GIF75
PCX75
TIF25
8
9
10
11
12
13
BMP50
GIF50
TIF75
computing_time (p=1)
Abbildung 3.8.: Reduzierung der Rechenzeit
Man beachte, da die Rechenzeit in Millisekunden angegeben und die rechte
Achse logarithmisch skaliert ist. Der nahezu lineare Anstieg der Kurve fur p=1
bedeutet somit exponentielle Rechenzeit. In jedem Lauf kommen neue Attribute hinzu, wobei die meisten davon weniger als 5 mal angefragt werden. Diese
werden im 2. Fall (p=5) herausge
ltert, so da hier die Rechenzeit konstant
niedrig bleibt.
3.5 Reduzierung der Rechenzeit
26
Die relativ lange Rechenzeit im ersten Optimierungslauf liegt am Just-in-TimeCompiler von Java: Programmfragmente wie die Methoden zur Optimierung
werden erst dann compiliert, wenn sie zum erstenmal gebraucht werden. Dies
kann verhindert werden, indem der Just-in-Time-Compiler deaktiviert wird.
Dazu mu das Programm mit folgender Syntax aufgerufen werden:
java -Djava.compiler=NONE Scenery standard
Aus Ezienzgrunden sollte dies aber nur in Ausnahmefallen gemacht werden.
Das Einfugen und Loschen von Bildern in die Datenbank ist sehr zeitaufwendig
und sollte deshalb auf ein Minimum reduziert werden. Falls ein Attribut jedoch
nur in jedem zweiten oder dritten Lauf angefragt wird, schlagt der Optimierungsalgorithmus u.U. ein standiges Speichern und Loschen dieses Attributs
vor. Um dies zu verhindern, kann mit dem Parameter q die Anzahl der Optimierungen eingestellt werden, fur die ein Attribut verwendet werden soll. Wird
beispielsweise ein Bild in GIF100 angefragt und ist q=3, so ist diese Anfrage fur
die nachsten drei Optimierungen relevant.
A_phys (q=1)
GIF100 BMP100 PCX100 GIF100 BMP100 PCX100 GIF100 BMP100 PCX100 GIF100 BMP100 PCX100 GIF100 BMP100 PCX100
12
120000
10
100000
80000
8
total_time
(ms)
number
of requests
6
60000
4
40000
2
20000
0
0
GIF100
GIF100 BMP100 BMP100 BMP100 BMP100 BMP100 BMP100 BMP100 BMP100 BMP100 BMP100 BMP100 BMP100 BMP100
BMP100 GIF100 GIF100 GIF100 GIF100 GIF100 GIF100 GIF100 GIF100 GIF100 GIF100 GIF100 GIF100 GIF100
PCX100 PCX100 PCX100 PCX100 PCX100 PCX100 PCX100 PCX100 PCX100 PCX100 PCX100 PCX100 PCX100
A_phys (q=3)
BMP100
GIF100
PCX100
total_time (q=1)
total_time (q=3)
Abbildung 3.9.: Beispiel mit q=1 und q=3
Abbildung 3.9 zeigt die mogliche Zeitersparnis bei geschickter Wahl von q.
Selbst in diesem kleinen Beispiel (100 TIF-Bilder, nur drei angefragte Attribute) lat sich dadurch ab der 4. Optimierung u ber eine Minute Zeit pro Lauf
einsparen.
3.6 Ausfuhrliche Beispiele
27
Allerdings sollte q nicht beliebig gro gewahlt werden, da sonst u.U. sehr viele
verschiedene Attribute in die Optimierung eingehen und somit der Rechenaufwand wieder ansteigt.
Die Abbildung 3.10 verdeutlicht den mit zunehmender Zahl der zu berucksichtigten Attribute exponentiell ansteigenden Rechenaufwand.
100000
40
35
10000
30
25
number
of requests
20
1000
computing_time
(log scale, ms)
100
15
10
10
5
1
0
1
2
3
4
5
6
7
8
9
10
run
11
12
13
14
15
16
17
18
19
BMP100
BMP75
BMP50
BMP25
GIF100
GIF75
GIF50
GIF25
JPG100
JPG75
JPG50
JPG25
PCX100
PCX75
PCX50
PCX25
computing_time (q=100)
computing_time (q=1)
Abbildung 3.10.: Beispiel mit q=1 und q=100
Die Wahl der Parameter p und q ist also eine schwerwiegende Entscheidung,
die stark von der jeweiligen Anwendung abhangt. In der Praxis haben p=5 und
q=2 i.a. recht gute Ergebnisse geliefert.
3.6. Ausfuhrliche Beispiele
In diesem Abschnitt sollen praxisnahe Szenarien analysiert werden.
3.6.1. Anfragen an eine Heraldik-Datenbank
Der Lehrstuhl fur Datenbanken und Informationssysteme der Universitat Augsburg analysiert im Heron-Projekt (Informationen dazu im Internet1 und in
1
http://heron.informatik.uni-augsburg.de/
3.6 Ausfuhrliche Beispiele
28
KEUB+ 98]) mittelalterliche Familien- und Amtswappen. Die zugrundeliegenden Abbildungen wurden aus Johann Siebmachers "Wappenbuch\ (Sie56]) eingescannt (Format: TIF, Groe: jeweils 1 MB) und in einer DB2-Datenbank
gespeichert.
Da die Abbildungen einem breiten Personenkreis zuganglich gemacht werden
sollen, kann die Datenbank uber das Internet angefragt werden. Aus diesem
Grund werden fur das Anfragepro
l des nachfolgenden Szenarios folgende Annahmen getroen:
♦
♦
♦
Die angefragten Formate sind GIF und
auf dem Browser und PS zum Ausdrucken.
GIF- und
ahlt,JPG-Bilder werden h
au
g in niedriger Qualitat ausgew
um das Browsen zu beschleunigen nur bei Interesse fur ein bestimmtes
Wappen fordert der Benutzer dann bessere Auosungen an.
Das da
Postscript-Format
zum
wird nur in der
at angefragt,
Drucken stets die beste Bildqualitat verwendet wird.
Abbildung 3.11.: Einstellungen fur das Heron-Beispiel
3.6 Ausfuhrliche Beispiele
29
Das Anfragepro
l kann den Abbildungen 3.11 und 3.12 entnommen werden.
Des weiteren wird unterstellt, da in der Datenbank 500 Bilder vorliegen. Die
Optimierungsparameter werden gema den Vorschlagen aus den vorherigen Abschnitten eingestellt, d.h. c_s=0.00001, c_a=0.00005, p=5 und q=2. Der Schalter use_total_store wird ebenso wie use_total_access eingeschaltet, dagegen bleibt use_stepfunction deaktiviert.
Der Parameter z entscheidet, mit welchem Gewicht die Speicher- bzw. Zugriskosten in die Gesamtkosten eingehen (vgl. De
nition 2.6). Die Zugriskosten
werden wie in Abschnitt 3.4 in Millisekunden berechnet und mussen monetar
bewertet werden, damit sie mit den Speicherkosten verglichen werden konnen.
Unterstellt man, da das Warten auf das gewunschte Bild dem Benutzer ArPF
so ergibt sich
beitszeit kostet und wird diese mit 72 DM
h = 0:002 ms angegeben,
0:002
1
z = 1+0:002 0:002. Damit konnen die Gesamtkosten als 100 DM bzw. Pfennig
interpretiert werden.
Auswertung der Zugriskosten
Abbildung 3.12 zeigt die Zugriskosten mit und ohne Optimierung. Dabei bedeutet letzteres, da die Bilder nur im TIF-Format vorliegen und alle anderen
konvertiert werden mussen.
2000000
1000
1800000
1600000
800
1400000
1200000
acc_cost
1000000 (ms)
600
number
of requests
800000
400
600000
400000
200
200000
0
0
GIF25 GIF25 GIF25 GIF25 GIF25 GIF25
GIF50 GIF50 GIF50 JPG25 JPG25 JPG25
JPG25 GIF50 GIF50 GIF50
A_phys
JPG50 JPG50
GIF25 GIF25
GIF25
JPG25
GIF50
JPG50
GIF25
JPG25
GIF50
JPG50
GIF25
JPG25
GIF50
JPG50
GIF25 GIF25 GIF25 GIF25 GIF25 GIF25
JPG25 JPG25 GIF50 GIF50
GIF50 GIF50
JPG50
GIF100
GIF75
GIF50
GIF25
JPG100
JPG75
JPG50
JPG25
PS100
acc_cost post_opt
acc_cost no_opt
Abbildung 3.12.: Vergleich der Zugriskosten
Aufgrund der Wahl der Parameter geben hier die Zugriskosten die Ladezeiten
3.6 Ausfuhrliche Beispiele
30
fur alle Anfragen in Millisekunden an. Damit erklaren sich auch die hohen
Zahlen an der rechten Achse.
Im ersten Lauf sind die optimalen Zugriskosten sehr gering. Ursache dafur
sind die gespeicherten GIF25-Bilder, die aufgrund ihrer geringen Groe kaum
Ladezeit benotigen.
Die Optimierung ermoglicht eine immense Zeitersparnis, die durch den Unterschied der beiden Kurven deutlich wird. Im Balkendiagramm aus Abbildung
3.13 wird diese Zeitdierenz (in Minuten umgerechet) dargestellt.
14
12
10
8
6
time
(min)
4
2
0
1
2
3
4
5
6
7
8
9
run
10
11
12
13
14
15
16
17
saved time (post_opt vs no_opt)
Abbildung 3.13.: Absolute Einsparung an Zugriskosten
Im funften Lauf werden beispielsweise bei 600 Anfragen (200 GIF25, 150 GIF50,
100 GIF75, 50 GIF100 und 100 JPG25) uber 10 Minuten Zeit eingespart, das
entspricht einer Verbesserung von u ber 60 %, wie aus Abbildung 3.14 ersichtlich
ist. Im Durchschnitt liegt der prozentuale Zeitgewinn aller 17 Laufe bei uber
50 %, so da sich fur die Endbenutzer eine enorme Ezienzsteigerung bemerkbar macht.
100
80
60
percent
40
20
0
1
2
3
4
5
6
7
8
9
10
run
11
12
13
14
15
16
17
saved time (percent)
Abbildung 3.14.: Prozentuale Einsparung an Zugriskosten
3.6 Ausfuhrliche Beispiele
31
Auswertung der Speicherkosten
Naturlich ist diese immense Verringerung der Zugriskosten nicht umsonst, vielmehr werden dafur hohere Speicherkosten in Kauf genommen. Deren Entwicklung ist in Abbildung 3.15 dargestellt. Dabei sind nur die von der Optimierung
verursachten Speicherkosten angegeben. Wird nicht optimiert, so wird auch
kein Attribut zusatzlich gespeichert und es entstehen auch keine Kosten (d.h.
Speicherkosten = 0).
600
1000
500
800
number
of requests
400
600
store_cost
(PF)
300
400
200
200
100
0
0
GIF25
GIF25
GIF25
GIF50
GIF25
GIF50
A_phys
GIF25
GIF50
JPG25
GIF25
JPG25
GIF50
GIF25
JPG25
GIF50
JPG50
GIF100
GIF25
JPG50
store_cost post_opt
GIF25
JPG25
GIF50
JPG50
GIF25
JPG25
GIF50
JPG50
GIF75
JPG100
JPG25
GIF25
JPG25
GIF50
JPG50
GIF25
JPG25
GIF50
JPG50
GIF25
JPG25
GIF50
JPG50
GIF25
JPG25
GIF50
GIF25
GIF50
GIF25
GIF50
GIF25
GIF25
GIF50
JPG75
PS100
Abbildung 3.15.: Entwicklung der Speicherkosten
1
DM bzw. Pfennig angeGema obiger Wahl fur c_s werden die Kosten in 100
geben.
Deutlich ist zu erkennen, da die Speicherkosten mit zunehmender Zahl der zu
speichernden Attribute wachsen. Ebenso sieht man, da die Bilder in GIF50
etwa viermal soviel Speicherkosten verursachen als in GIF25 (Lauf 2 und 3,
bzw. Lauf 15 und 16). Die Ursache dafur ist, da die Bilder bei der Skalierung
von GIF25 nach GIF50 in zwei Dimensionen vergroert werden, so da sich der
Speicherbedarf vervierfacht.
Auswertung der Gesamtkosten
Die Gesamtkosten setzen sich aus den Speicher- und Zugriskosten zusammen
(vgl. De
nition 2.6). In Abbildung 3.16 sind die Kosten mit und ohne Optimierung dargestellt. Die gestrichelte Linie zeigt den Kostenverlauf bei physikalischer Speicherung aller angefragten Attribute. Diese sind relativ hoch, da v.a.
die Speicherung im Postscript-Format teuer ist. Im optimalen Fall wird PS nie
physikalisch gespeichert.
3.6 Ausfuhrliche Beispiele
32
1000
7000
6000
800
number
of requests
5000
cost
(PF)
4000
600
3000
400
2000
200
1000
0
0
GIF25
GIF25
GIF25 GIF25
GIF50 GIF50
A_phys
GIF25 GIF25 GIF25
GIF50 JPG25 JPG25
JPG25 GIF50 GIF50
JPG50
GIF25
JPG25
GIF50
JPG50
GIF25
JPG25
GIF50
JPG50
GIF25
JPG25
GIF50
JPG50
GIF25
JPG25
GIF50
JPG50
GIF25 GIF25 GIF25 GIF25 GIF25
JPG25 JPG25 GIF50 GIF50
GIF50 GIF50
JPG50
GIF25
GIF100
GIF75
GIF50
GIF25
JPG100
JPG75
JPG50
JPG25
PS100
cost post_opt
cost no_opt
cost save_all
Abbildung 3.16.: Verlauf der Gesamtkosten
Hier lat sich nun der tatsachliche monetare Gewinn der Optimierungen ablesen, da die Parameter entsprechend gewahlt worden sind. Die Dierenz zwischen
den Kostenkurven mit und ohne Optimierung und der damit korrespondierende prozentuale Gewinn sind in den beiden Balkendiagrammen in 3.17 und 3.18
dargestellt.
1000
800
cost
(PF)
600
400
200
0
1
2
3
4
5
6
7
8
9
run
10
11
12
13
14
15
16
saved cost (post_opt vs no_opt)
Abbildung 3.17.: Absolute Kosteneinsparung
17
3.6 Ausfuhrliche Beispiele
33
60
50
40
percent
30
20
10
0
1
2
3
4
5
6
7
8
9
10
run
11
12
13
14
15
16
17
saved cost (percent)
Abbildung 3.18.: Prozentuale Kosteneinsparung
Da hier Zugris- und Speicherkosten gemeinsam betrachtet werden, ist der Gewinn naturlich nicht so gro wie bei den Zugriskosten allein. Trotzdem konnen
beispielsweise in den Laufen 7 - 11 fast 10 DM eingespart werden. Noch deutlicher wird der Nutzen, wenn man wieder die prozentuale Verbesserung betrachtet: Im Mittel werden pro Lauf etwa 30 % an Gesamtkosten eingespart.
Ab dem 9. Lauf rutscht die Verbesserung unter die 30 %-Marke. Dies wird durch
die Anfragen an das Postscript-Format verursacht: Der Optimierer lehnt es aufgrund ihrer Groe ab, PS-Bilder zu speichern. Folglich kann fur diese Anfragen
keine Einsparung erreicht werden, so da auch die Gesamtverbesserung sinkt.
Sortiert man die Laufe nach ihrer prozentualen Verbesserung und bildet mehrere
Klassen (0 - 10 % Verbesserung, 10 - 20 %, 20 - 30 %, 30 - 40 %, 40 - 50 %,
> 50 %), so lat sich dies in einem Tortendiagramm (Abbildung 3.19) darstellen.
20 - 30 %
30 - 40 %
40 - 50 %
10 - 20 %
> 50 %
Abbildung 3.19.: Verteilung der Laufe gema der prozentualen Verbesserung
Hier wird deutlich, da die Optimierung nicht nur in Einzelsituationen, sondern
in einem Groteil der Laufe gute Ergebnisse liefert, denn in uber 23 der Falle
liegt die Verbesserung zwischen 20 und 40 % und in 15 der Laufe sogar uber
40 %.
3.6 Ausfuhrliche Beispiele
34
Ebenso lohnt es sich, die Verbesserung in jedem einzelnen Lauf zu betrachten,
d.h. man vergleicht die Kosten vor und nach jeder Optimierung. Dabei werden
bei der Berechnung der Kosten vor der Optimierung (pre opt) die momentan
gespeicherten Attribute berucksichtigt. Abbildung 3.20 zeigt den Verlauf der
Kostenkurven.
3000
1000
2500
800
number
of requests
2000
600
cost
1500
400
1000
200
500
0
0
GIF25
GIF25
GIF25
GIF50
GIF25
GIF50
A_phys
GIF25
JPG25
GIF50
GIF25
GIF50
JPG25
GIF25
JPG25
GIF50
JPG50
GIF25
JPG25
GIF50
JPG50
GIF25
JPG25
GIF50
JPG50
GIF25
JPG25
GIF50
JPG50
GIF25
JPG25
GIF50
JPG50
GIF25
JPG25
GIF50
JPG50
GIF25
JPG25
GIF50
GIF25
GIF50
GIF25
GIF50
GIF25
GIF100
GIF75
GIF50
GIF25
JPG100
JPG75
JPG50
JPG25
PS100
cost post_opt
cost pre_opt
GIF25
Abbildung 3.20.: Vergleich der pre- und postoptimalen Kosten
60
50
40
percent
30
20
10
0
1
2
3
4
5
6
7
8
9
run
10
11
12
13
14
15
16
17
saved cost (post_opt vs pre_opt)
Abbildung 3.21.: Prozentuale Verbesserung in jedem Lauf
3.6 Ausfuhrliche Beispiele
35
In den Fallen, in denen die Optimierung keine A nderung in Aphys induziert,
sind diese beiden Kosten gleich (Laufe 2, 4, 6, 8 - 12, 15 und 17). Ansonsten
ermoglicht die Optimierung eine Verbesserung, die naturlich nicht so auallig
ist wie die in Abbildung 3.16. Der prozentuale Gewinn ist aus Abbildung 3.21
ersichtlich.
3.6.2. Abfragen von Aktiencharts
Anleger wollen standig uber die aktuellen Kurswerte ihrer Wertpapiere informiert sein. Banken und Anlageberater stellen deshalb sog. Aktiencharts (graphische Darstellung eines Kursverlaufs) uber das Internet bzw. per Faxabruf
zur Verfugung.
Abbildung 3.22.: Einstellungen fur das Aktiencharts-Beispiel
In diesem Szenario sollen entsprechende Anfragen simuliert werden. Dazu werden folgende Annahmen gemacht:
♦
Format.
u ber das Internet fordern eine Ausgabe der Charts
Dieim
Anfragen
GIF-
3.6 Ausfuhrliche Beispiele
♦
♦
♦
36
Faxabrufe verlangen die Ausgabe in ein
Beispiel wird das Faxformat IPS verwendet, das von der Firma Brooktrout2 zur Datenubertragung an Faxkarten eingefuhrt wurde.
otigt.
Zum Ausdrucken wird gelegentlich das
Die IPS- und GIF-Bilder werden in hoh
Auosung angefragt.
Das Anfragepro
l ist aus den Abbildungen 3.22 und 3.23 ersichtlich.
Des weiteren wird unterstellt, da in der Datenbank 700 Charts (Format: BMP)
vorliegen, deren Groe jeweils etwa 1 MB betragt.
Die Zugriskosten werden wie zuvor in Millisekunden berechnet, so da der Button use_total_access eingeschaltet und c_a=0.00005 gewahlt werden
mu. Die Speicherkosten werden hier mittels einer Treppenfunktion berechnet, d.h. use_total_store und use_stepfunction werden aktiviert. Dabei
wird angenommen, da Tablespaces mit 500 MB Speicher verwendet werden
und das Einrichten eines neuen Tablespace jeweils 20 DM kostet (verursacht
durch die Festplattenkosten bzw. Arbeitszeit). Da die Zugriskosten in Millisekunden und die Speicherkosten in DM berechnet werden, wird der Parameter
z=0.00002 gesetzt (zwei Zehnerpotenzen kleiner als im vorherigen Beispiel, siehe Seite 29).
Weiterhin werden p=5 und q=2 gewahlt.
1600000
500
1400000
400
1200000
number
of requests
1000000
acc_cost
800000 (ms)
300
200
600000
400000
100
200000
0
GIF50 GIF50 GIF50
GIF100 GIF100 GIF100
IPS100 IPS100 IPS100
A_phys
0
GIF50
GIF100
IPS50
IPS100
GIF50 GIF50 GIF50
IPS50 GIF100 GIF100
GIF100 IPS100 IPS100
IPS100
GIF100
GIF50
IPS100
PS100
acc_cost no_opt
acc_cost post_opt
Abbildung 3.23.: Verlauf der Zugriskosten
2
http://www.brooktrout.com/
IPS50
3.6 Ausfuhrliche Beispiele
37
Auswertung der Zugriskosten
Ohne Optimierung verlaufen die Zugriskosten entsprechend der Zahl der Anfragen (dunne Kurve aus Abbildung 3.23), so da insbesondere in den Laufen
4, 5 und 12-14 diese Kosten sehr hoch sind. Besonders in diesen Fallen bringt
die Optimierung einen hohen Gewinn, da durch das Speichern eines GIF- oder
IPS-Formats viel Zeit eingespart werden kann: Zum einen entfallt fur solche Attribute naturlich die aufwendige Formatkonvertierung, zum andern sind GIFund IPS-Bilder komprimiert, so da sie viel kleiner als die Originale im BMPFormat sind und damit kurzere Ladezeiten benotigen.
25
20
15
time
(min)
10
5
0
1
2
3
4
5
6
7
8
run
9
10
11
12
13
14
15
16
saved time (post_opt vs no_opt)
Abbildung 3.24.: Absolute Verbesserung der Zugriskosten
100
80
60
percent
40
20
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
run
saved time (percent)
Abbildung 3.25.: Prozentuale Verbesserung der Zugriskosten
Die eingesparte Gesamtzeit liegt deshalb in den Laufen 4-6 und 12-15 zwischen
18 und 25 Minuten, wie aus Abbildung 3.24 abgelesen werden kann. Die prozentuale Verbesserung liegt in diesen Fallen bei u ber 90 %, teilweise ist sie nur
knapp unter 100 %.
Trotz dieser immensen Einsparungen lehnt der Optimierer in vielen Fallen (1-3,
7-11 und 16) das Speichern zusatzlicher Attribute ab. Dies liegt naturlich an
den Speicherkosten, die im folgenden analysiert werden sollen.
3.6 Ausfuhrliche Beispiele
38
Auswertung der Speicherkosten
In diesem Szenario wird ein treppenformiger Verlauf der Speicherkosten unterstellt: Jeder angefangene 500-MB-Block kostet 20 DM. Entsprechend verlaufen
die Speicherkosten in 20-DM-Schritten, wie aus Abbildung 3.26 ersichtlich wird.
20
500
400
15
number
of requests
300
store_cost
(DM)
10
200
5
100
0
0
GIF50 GIF50 GIF50
GIF100 GIF100 GIF100
IPS100 IPS100 IPS100
GIF100
GIF50
IPS100
A_phys
IPS50
GIF50 GIF50 GIF50 GIF50
GIF100 IPS50 GIF100 GIF100
IPS50 GIF100 IPS100 IPS100
IPS100 IPS100
PS100
store_cost post_opt
Abbildung 3.26.: Verlauf der Speicherkosten
Werden keine Attribute zusatzlich gespeichert, so sind die Speicherkosten naturlich gleich Null (Lauf 1-3 und 7-11 und 16), ansonsten wird maximal ein
500-MB-Block benotigt, so da die Kosten hochstens 20 DM betragen. Hierbei
wird auch die Komprimierung durch die Formate GIF und IPS deutlich: Die
Speicherung aller 700 Bilder in vier GIF- und IPS-Attributen (Laufe 12 und
13) braucht weniger als 500 MB Speicher, obwohl ein Bild im Original 1 MB
gro ist.
Auswertung der Gesamtkosten
Werden alle angefragten Attribute gespeichert (GIF100, GIF50, IPS100, IPS50,
PS100), so werden zwei 500-MB-BLocke benotigt, so da die Speicherkosten
40 DM betragen und die Gesamtkosten nahezu konstant bei 40 DM liegen
(cost save all, gestrichelte Linie in Abbildung 3.27).
Die dunne durchgezogene Linie zeigt den Kostenverlauf, falls keine Optimierung
durchgefuhrt wird und alle angefragten Attribute stets aus den Referenzbildern
konvertiert werden. Andernfalls ist wieder eine groe Kosteneinsparung moglich,
wie der Vergleich mit der dickeren Linie (cost post opt) zeigt.
Durch die Optimierung konnen die Kosten um bis zu 10 DM (Lauf 13) reduziert
werden, damit werden im Vergleich zu "no opt\ uber 30 % eingespart. In den
Laufen, in denen der Optimierer eine physikalische
Speicherung von Attributen
3.6 Ausfuhrliche Beispiele
39
500
40
400
number
of requests
300
30
cost
(DM)
20
200
10
100
0
0
GIF50 GIF50 GIF50
GIF100 GIF100 GIF100
IPS100 IPS100 IPS100
GIF100
PS100
GIF50
GIF100
IPS50
IPS100
A_phys
GIF50
cost save_all
GIF50 GIF50 GIF50
IPS50 GIF100 GIF100
GIF100 IPS100 IPS100
IPS100
IPS100
cost save_no
IPS50
cost post_opt
Abbildung 3.27.: Verlauf der Gesamtkosten
vorschlagt (4-6, 12-15) werden im Durchschnitt etwa 20 % gespart, mittelt man
uber alle Laufe, so betragt die Einsparung knapp 10 %.
30
25
20
percent
15
10
5
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
run
saved cost (percent)
Abbildung 3.28.: Prozentuale Kostenersparnis
Werden die Laufe gema ihrer prozentualen Verbesserung auf die Kategorien
< 10%, 10 ; 20%, 20 ; 30%, 30 ; 40%, 40 ; 50% und > 50% verteilt, so ist
die < 10%-Kategorie naturlich am groten (Abbildung 3.29), da bereits 9 der
16 Laufe keine Verbesserung liefern. Trotzdem liegt in 51 der Falle der Gewinn
zwischen 20 und 40 %.
3.6 Ausfuhrliche Beispiele
40
< 10 %
30 - 40 %
10 - 20 %
20 - 30 %
Abbildung 3.29.: Verteilung der Laufe gema der prozentualen Verbesserung
Schlielich soll auch hier der Nutzen in jedem einzelnen Lauf analysiert werden,
indem Kosten vor und nach der Optimierung verglichen werden (Abbildung
3.30).
500
40
400
number
of requests
300
30
cost
(DM)
20
200
10
100
0
0
GIF50 GIF50 GIF50
GIF100 GIF100 GIF100
IPS100 IPS100 IPS100
GIF100
PS100
GIF50
cost post_opt
A_phys
GIF50
GIF100
IPS50
IPS100
IPS100
cost pre_opt
GIF50 GIF50 GIF50
IPS50 GIF100 GIF100
GIF100 IPS100 IPS100
IPS100
IPS50
Abbildung 3.30.: Vergleich der pre- und postoptimalen Kosten
Da die preoptimalen Kosten von den vor der Optimierung gespeicherten Attributen abhangen, konnen die postoptimalen Kosten nur dann geringer sein,
wenn die Optimierung eine Veranderung in Aphys induziert (Laufe 4, 7, 12, 14
und 16). Die prozentuale Verbesserung in jedem Lauf ist in Abbildung 3.31
dargestellt.
3.6 Ausfuhrliche Beispiele
41
30
25
20
percent
15
10
5
0
1
2
3
4
5
6
7
8
run
9
10
11
12
13
14
15
16
saved cost (post_opt vs pre_opt)
Abbildung 3.31.: Prozentuale Verbesserung in jedem Lauf
Wird durch die Optimierung eine A nderung der physikalisch gespeicherten Attribute verursacht, so betragt in diesen Laufen die Verbesserung etwa 20 %.
Lauf 14 stellt dagegen eine Ausnahme dar: Die Verbesserung ist so gering, da
sie in der Graphik verschwindet.
In diesem Kapitel wurden die Optimierungsalgorithmen an umfangreichen praxisrelevanten Beispielen getestet. Deren Auswertung ergab, da durch die Formatoptimierung eine enorme Kosteneinsparung moglich ist, die sich fur den
Endbenutzer vor allem durch kurzere Ladezeiten bemerkbar macht.
4. Implementierung
Im Kapitel 2 wurden Algorithmen zur Formatoptimierung vorgestellt. Der Basisalgorithmus 2.1 wurde bereits von Peter Rieger (Rie97]) in C/ESQL realisiert,
die auf Algorithmus 2.2 (einschlielich samtlicher Modi
kationen) basierende
Re-Implementierung in Java/JDBC ist Bestandteil der vorliegenden Arbeit.
Dazu werden in diesem Kapitel die verwendete Programmiersprache Java und
die wesentlichen Aspekte der Implementierung vorgestellt.
Der Quellcode der Optimierung (Attribut.java und Optimierung.java, siehe
Anhang B) ist 1200 Zeilen lang, der der Oberachen umfat 800 (Scenery.java)
bzw. 300 (Opti.java) Zeilen. Samtliche Programmtexte nden sich auch im Internet1 .
4.1. Java und die Datenbankschnittstelle JDBC
Die Programmiersprache Java und die dazugehorigen Klassenbibliotheken bieten eine portable, interpretierbare, leistungsfahige, objektorientierte Entwicklungsumgebung. Damit konnen auch Programme erstellt werden, die u ber das
Internet verschickt und von einem Browser gestartet werden (sog. Applets).
Sie dienen v.a. zur Auockerung von Web-Seiten. Ebenso erlaubt Java aber
auch die Programmierung komplexer Applikationen, wie sie in dieser Arbeit
entwickelt werden.
Der zentrale Bestandteil eines Java-Programms ist die Klasse. Jede Variable
und jede Methode mu Bestandteil einer Klasse sein. Bei einer Applikation
mu in einer Klasse eine Methode
public static void main (String ] args)
vorliegen, die mit der main-Funktion in C-Programmen vergleichbar ist. Applets
enthalten keine main-Methode, da sie nicht selbstandig ablaufen, sondern von
einem Browser gestartet und beendet werden.
Daneben gibt es als Strukturierungsmittel sog. Pakete, die verwandte Klassen zusammenfassen. Gangige Pakete sind java.lang und java.util, die u.a.
Klassen fur Datenstrukturen, Zeichenkettenoperationen und Fehlerbehandlung
beinhalten. In jedem Java-Programm wird java.lang automatisch geladen,
andere Pakete mussen mit dem Befehl import zu Beginn des Java-Programms
eingebunden werden, z.B.:
1
http://heron.informatik.uni-augsburg.de/tmplobs/doc/main.htm
4.1 Java und die Datenbankschnittstelle JDBC
43
import java.util.*
Fur die Datenbankschnittstelle JDBC (Java Database Connectivity) steht das
Paket java.sql zur Verfugung, in dem Schnittstellen und Klassen de
niert
sind, deren Methoden den Zugri und die Manipulation von Datenbanktabellen
erlauben. (Eine Schnittstelle ist eine Klasse, deren Methoden noch nicht implementiert sind.) Diese sind unabhangig von der verwendeten Datenbanksoftware,
so da ein JDBC-Programm auf verschiedenen Datenbanksystemen lauahig
ist. Technisch wird das realisiert, in dem die Schnittstellen im java.sql-Paket
vom jeweiligen Datenbanksystem implementiert werden. Deshalb ist es erforderlich, zu Beginn eines JDBC-Programms einen datenbankspezi
schen Treiber
zu laden. Unter DB2 geschieht dies mit folgendem Programmfragment:
static
{
try
{
Class.forName("COM.ibm.db2.jdbc.app.DB2-Driver")
} catch(ClassNotFoundException x)
{
System.out.println("\nError loading DB2-Driver")
x.printStackTrace()
}
}
Bei Informix-Datenbanken wurde die funfte Zeile stattdessen
Class.forName("informix.api.jdbc.JDBCDriver")
lauten.
Nachdem das Paket java.sql und der Treiber geladen sind, konnen die Klassen
und die dazugehorigen Methoden der JDBC verwendet werden. Damit werden
u.a. folgende Funktionen zur Verfugung gestellt:
♦
und ohne "Auto Commit\
♦
♦
♦
u ber die Datenbank
utzung von statischem und dynamischem SQL
Aufbau einer Datenbankverbindung, Ve
Abfrage von Meta-Informationen
Unterst
Verwendung der UDFs, insbesondere au
Die Ergebnisse von SELECT-Anfragen werden ahnlich wie bei Embedded SQL
mit einem Cursor durchlaufen.
Beispiel
Gesucht sind die Formate und die Qualitatsstufen, in denen die Bilder momentan vorliegen.
4.2 Das Datenmodell
44
.
.
.
Connection con = DriverManager.getConnection("jdbc:db2:stefandb")
.
.
.
String sql = "SELECT DISTINCT mmdbsys.format(ext_image),quality"+
" FROM raw_image"
Statement stmt = con.createStatement()
ResultSet rs = stmt.executeQuery(sql)
while(rs.next)
{
String format = rs.getString(1)
int quality = rs.getInteger(2)
System.out.println(format+", "+quality)
}
Zunachst wird also eine Verbindung mit der Datenbank stefandb aufgebaut
und ein Objekt vom Typ Statement erzeugt. Die Anfrage wird als Zeichenkette
verschickt und die Ergebnismenge mit dem Cursor rs durchlaufen. Fur die UDF
format wurde hier das Schema mmdbsys mit angegeben. Dieser Zusatz kann entfallen, wenn mmdbsys der Variable CURRENT FUNCTION PATH hinzugefugt wird.
Das Argument ext_image bezeichnet eine Spalte vom Typ DB2Image in der
Tabelle raw_image (vgl. Datenmodell im nachsten Abschnitt).
Das Ergebnis kann beispielsweise so aussehen:
GIF,
GIF,
GIF,
GIF,
JPG,
JPG,
25
50
75
100
50
100
4.2. Das Datenmodell
Zur Speicherung der Bilder, der moglichen Formate und Konvertierungen und
der statistischen Daten wurde das in Abbildung 4.1 dargestellte Datenbankschema (Entity-Relationship-Modell) gewahlt.
Die eigentlichen Bilder werden unter ext_image (Datentyp: DB2Image) in der
Entitat raw_image gespeichert, Name und Beschreibung nden sich dagegen in
image. Dies erm
oglicht, da die Bilder in mehreren Formaten und Qualitatsstufen vorliegen, aber nur einmal beschrieben sind, so da keine Redundanzen
auftreten.
4.2 Das Datenmodell
raw_image
ext_image
name
quality
static
45
describes
image
name
description
selects_description
selects_picture
conversion
source_format
source_quality
target_format
target_quality
z_hist
avg_conv_time
is_allowed
uses_conversion
query_profile
date_time
name
source_format
source_quality
target_format
target_quality
target_image_sz
conv_time
age
Abbildung 4.1.: Datenmodell
Die Entitat conversion beinhaltet alle von den DB2-Extendern zur Verfugung
gestellten Formatkonvertierungen und markiert die momentan zulassigen mit
is_allowed=1. Ebenso wird hier die durchschnittliche Konvertierungszeit gespeichert. Diese kann standig aktualisiert werden: Neuere Daten (Gewicht:
1-z_hist) verbessern die alteren (Gewicht: z_hist).
In query_profile wird jede Anfrage registriert. Falls dabei konvertiert werden
mu, wird die benotigte Rechenzeit unter conv_time in Millisekunden gespeichert. Ebenso wird auch die Groe des dabei entstandenen Bildes vermerkt.
Die des Quellbildes mu nicht gespeichert werden, da sie mit der UDF size
berechnet werden kann. Die Spalte age gibt an, fur wieviele Optimierungen die
Anfrage bereits verwendet wurde. Sie dient auch der Entfernung nicht mehr
relevanter Querys.
Zu jeder Anfrage mu eine entsprechende Konvertierung existieren (Quell- und
Zielattribut durfen auch gleich sein), das Quellattribut des Bildes mu in
raw_image und die Beschreibung in image vorliegen. Dies sichern die Relationships uses_conversion, selects_picture und selects_description. Die
Relationship describes ordnet jedem gespeicherten Bild eine dazugehorige Beschreibung zu.
Die Tabelle opti_log in Abbildung 4.2 wird nicht fur die Optimierung benotigt,
sondern dient zum Speichern der Parameter und Ergebnisse der einzelnen Optimierungslaufe. Es werden die Speicher- und Zugriskosten vor (preopt) und
nach (postopt) der Optimierung eingetragen, ebenso die Kosten, falls alle angefragten Attribute (saveall) oder nur das Referenzformat (saveno) gespeichert
werden. Die Gesamtkosten konnen aus dem Parameter z und den jeweiligen
Speicher- und Zugriskosten ermittelt werden. Zusatzlich werden auch die reinen Rechenzeiten (computing_time) und die Gesamtdauer (total_time) vermerkt. Schlielich gibt a_phys als Zeichenkette die Menge der zu speichernden
4.3 Die Implementierung der Klassen
46
Attribute an.
opti_log
datetime
static_format
z
c_s
c_a
c_c
p
q
number_of_images
hd_size
hd_cost
computing_time
total_time
acc_cost_preopt
store_cost_preopt
acc_cost_saveall
store_cost_saveall
acc_cost_saveno
store_cost_saveno
acc_cost_postopt
store_cost_postopt
a_phys
Abbildung 4.2.: Die Tabelle opti log
Die Entitaten werden im Relationenmodell zu Tabellen, die Relationships werden durch Fremdschlussel realisiert.
Ein Shell-Script zur Ausfuhrung der entsprechenden SQL-Statements fur DB2Datenbanken ndet sich im Anhang A.1.
4.3. Die Implementierung der Klassen
Java-Programme konnen modularisiert werden, indem der Quellcode auf mehrere sinnvolle Klassen verteilt wird. Die Klasse Attribut dient der Speicherung
von Attributinformationen, in Optimization wird die eigentliche Optimierung
durchgefuhrt, und Opti erzeugt eine graphische Benutzeroberache zur Kon
guration der Optimierung. Kurzinformationen zu den wichtigsten Variablen
und Methoden dieser Klassen nden sich auch im Internet2 .
4.3.1. Die Klasse Attribut
Hier werden die zur Optimierung notwendigen Informationen u ber die Attribute
gespeichert. Diese sind im einzelnen:
2
http://heron.informatik.uni-augsburg.de/tmplobs/doc/tree.html
4.3 Die Implementierung der Klassen
47
Variable
Beschreibung
acc_cost
Zugriskosten fur dieses Attribut
avg_acc
durchschnittliche Zugrisrate oder absolute Zugriszahl
avg_conv_time
Dauer einer Konvertierung vom Referenzformat bzw.
von "besseren\ Attributen in dieses Attribut
in Anlehnung an die Konvertierungsregeln auf Seite 10
(realisiert als Integer-Feld der Lange vier)
avg_image_size durchschnittliche Bildgr
oe
bit_best
=1, falls dieses Attribut nach der Optimierung zu
Aphys gehort, sonst bit_best=0
bit_used
=1, falls dieses Attribut im aktuellen Schritt
zu Aphys gehort, sonst bit_used=0
format
Bildformat
quality
Bildqualitat
Die einzige Methode dieser Klasse heit equals und testet zwei Attribute auf
Gleichheit.
4.3.2. Die Klasse Optimization
Die Optimierung wird in Methoden dieser Klasse realisiert.
Die Variablen z, c_s, c_a, c_t, c_c, p und q realisieren die in Kapitel 2
bereits vorgestellten Parameter. Die boolschen Variablen use_total_store,
use_stepfunction und use_total_access entsprechen den auf Seite 19 vorgestellten Schaltern der graphischen Oberache Scenery, ebenso die IntegerFelder hd_size und hd_cost.
Aktualisierung der durchschnittlichen Konvertierungszeiten
Fur die Anfragen, die seit der letzten Optimierung gestellt worden sind, wird fur
jede verwendete Konvertierung die durchschnittliche Rechenzeit conv_time_new
bestimmt. Damit wird die Spalte avg_conv_time der Tabelle conversion gema
folgender Vorschrift angepat:
avg_conv_time=z_hist*avg_conv_time + (1-z_hist)*conv_time_new
Der Parameter z_hist kann fur jede Konvertierung individuell angegeben werden, so da beispielsweise im Falle unbekannter Konvertierungszeiten z_hist=0
gesetzt werden kann und im anderen Extremfall, falls die Rechenzeit bekannt
und stets konstant ist, z_hist=1 gewahlt wird. Im allgemeinen wird jedoch
z_hist 2 (0 1) gelten.
Analyse der statistischen Daten
Vor der Optimierung mussen naturlich die statistischen Daten (durchschnittliche Bildgroe, Konvertierungszeiten usw.) aus der Datenbank gelesen werden.
4.3 Die Implementierung der Klassen
48
Die angefragten Attribute werden der Tabelle query_profile entnommen. Dabei mussen die Parameter p und q beachtet werden, so da der SQL-String
lautet:
String sql = "SELECT target_format, target_quality, "+
"avg(target_image_sz), count(*) "+
"FROM query_profile "+
"WHERE age < "+ p +
"GROUP BY target_format, target_quality "+
"HAVING count(*) >= " + q
Jedes Ergebnis wird in einem Objekt der Klasse Attribut gespeichert. Aus obiger Anfrage werden das Format, die Qualitat, die durchschnittliche Bildgroe
und die Anzahl der Anfragen ermittelt. Letztere wird direkt in avg_acc gespeichert, falls die Gesamtzugriszahl relevant ist (use_total_access=true),
andernfalls wird durch die Anzahl aller Zugrie dividiert und die damit errechnete Zugrisrate in avg_acc abgelegt.
Zu jedem Attribut mussen noch die Konvertierungszeiten vom Referenzformat
und von den "besseren\ Attributen aus der Tabelle conversion ausgelesen
werden. Fur das Attribut a lauten die Statements:
String sql = "SELECT avg_conv_time FROM conversion " +
"WHERE target_format = '" + a.format + "' " +
"AND target_quality = " + a.quality + " "+
"AND source_format = '" + static_format + "' " +
"AND source_quality = " +static_quality
und
String sql = "SELECT avg_conv_time FROM conversion " +
"WHERE target_format = '" + a.format + "' " +
"AND target_quality = " + a.quality + " "+
"AND source_format = '" + a.format + "' " +
"AND source_quality > " +a.quality + " " +
"ORDER BY source_quality DESC"
Dabei sind static_format und static_quality Referenzformat und Referenzqualitat, wobei meist static_quality=100 gelten wird. Die einfachen Anfuhrungsstriche kennzeichnen Strings in DB2. Die Ergebnisse werden in einer festgelegten Reihenfolge in das Feld avg_conv_time des jeweiligen Attributs eingetragen.
Die durchschnittliche Bildgroe eines Attributs wird mit avg(target_image_sz)
aus den angefragten Bildern geschatzt. Bei Attributen, in denen die Bilder bereits vor der Optimierung gespeichert waren, kann diese mit
4.3 Die Implementierung der Klassen
49
String sql = "SELECT avg(mmdbsys.size(ext_image)) "+
"FROM raw_image "+
"WHERE mmdbsys.format(ext_image) = '" + a.format+
"' AND quality = " + a.quality
genauer berechnet werden, da hier der Durchschnitt uber alle Bilder bestimmt
wird.
Realisierung der Potenzmenge der Attribute
Die Attribute werden in der Datenstruktur Vector (aus dem Paket java.util)
abgelegt. Dies ist eine Liste, in der die einzelnen Elemente indiziert werden, so
da leicht auf bestimmte Attribute zugegrien werden kann. Nachteilig ist, da
ein Vector nur Objekte kennt, die bei jedem Zugri in den entsprechenden
Datentyp (hier die Klasse Attribut) umgewandelt werden mussen.
Fur Aphys mu jede mogliche Teilmenge der Attribute getestet werden. Dazu
wird die Variable bit_used verwendet, die zu Beginn fur alle Attribute =0 ist,
d.h. kein Attribut ist physikalisch gespeichert. Die u brigen Teilmengen werden analog zur Implementierung in Rie97] erzeugt: Die Menge der Variablen
bit_used wird als Bin
arzahl interpretiert, die in jedem Optimierungsschritt
inkrementiert wird.
bit_used
1. Optimierungsschritt
Attribut 1 Attribut 2 Attribut 3
0
0
0
bit_used
0
0
1
bit_used
0
1
0
bit_used
0
1
1
bit_used
1
0
0
2. Optimierungsschritt
3. Optimierungsschritt
4. Optimierungsschritt
5. Optimierungsschritt
usw.
In jedem Schritt werden die Kosten berechnet und mit den Kosten der bisher
besten Menge Aphys verglichen. Bei einer Verbesserung wird die aktuelle Menge
Aphys gemerkt, indem hier bit_best=1 gesetzt wird. Mit diesem Vorgehen steht
am Ende die optimale Menge der zu speichernden Attribute fest.
Berechnung der Speicherkosten
Zunachst wird die Summe der durchschnittlichen Bildgroen a.avg_image_size
aller Attribute a 2 Aphys bestimmt. Ist der Gesamtspeicherbedarf relevant
(use_total_store=true), so wird diese Summe zusatzlich mit der Bildanzahl
multipliziert.
4.3 Die Implementierung der Klassen
50
Falls keine Treppenfunktion verwendet werden soll (use_stepfunction=
false), so sind die Speicherkosten das Produkt aus dieser Summe mit der
Variablen c_s.
Andernfalls ist die Berechnung etwas aufwendiger:
Die Treppenfunktion sei durch die Arrays hd_size und hd_cost gegeben, wobei
die Groe in MB angegeben ist (z.B. hd_size=100,150,250 und hd_cost=50,
90,140). Reichen die vorgegebenen Gr
oen nicht aus, so soll mit der letzten
Angabe (im Beispiel Groe 250 und Kosten 140) interpoliert werden. Dies kann
deaktiviert werden, indem eine zusatzliche Platte mit (fast) unendlichen Kosten
hinzugefugt wird (hier hd_size=100,150,250,1 und hd_cost=50,90,140,
999999).
Zur Berechnung der Speicherkosten mu zunachst die obige Summe durch
1000000 dividiert werden, da diese in Byte angegeben ist. Aus dem resultierenden Speicherbedarf (in MB) werden die benotigten Platten ermittelt, die
Speicherkosten ergeben sich dann aus der Summe der Kosten dieser Platten.
Berechnung der Zugriskosten
In jedem Optimierungsschritt wird die Attributmenge A in zu speichernde und
zu berechnende Attribute zerlegt.
Fur ein physikalisch gespeichertes Attribut a sind die Zugriskosten gema De
nition 2.9 das Produkt aus der durchschnittlichen Bildgroe (a.avg_image_size)
und dem Parameter c_a und werden unter a.acc_cost abgelegt.
Bei den zu berechnenden Attributen mu zunachst das Quellformat ermittelt
werden. Dies geschieht unter Berucksichtigung der momentan zu speichernden
Attribute und den Konvertierungsregeln auf Seite 10. Daraus ergibt sich, welche
Konvertierungszeit aus dem Array a.avg_conv_time verwendet werden mu.
Die Zugriskosten ergeben sich dann additiv aus der mit c_c skalierten Konvertierungszeit und der mit c_a multiplizierten durchschnittlichen Bildgroe des
Quellformats.
Die Summe uber die mit der Variable a.avg_acc gewichteten attributbezogenen
Zugriskosten liefert die Gesamtzugriskosten. Ist use_total_access=false,
so gibt a.avg_acc die Zugrisrate (2 0 1]) an, andernfalls die tatsachliche Zahl
der Anfragen an dieses Attribut (vgl. Seite 48).
Bestimmung der Optimalitat
Die Gesamtkosten ergeben sich aus der Summe der Speicherkosten (Gewicht:
(1-z)) und der Zugriskosten (Gewicht: z). Eine Zerlegung der Attributmenge
in Aphys und Acomp ist optimal, wenn diese Gesamtkosten minimal sind.
4.3 Die Implementierung der Klassen
51
Aktualisierung der Datenbank
Zunachst werden die Bilder in den Attributen geloscht, die vor der Optimierung
gespeichert und nun berechnet werden. Zum Loschen des Formats f in der
Qualitat q dient folgendes Statement:
String sql = "DELETE FROM raw_image "+
"WHERE mmdbsys.format(ext_image) = '" + f +
"AND quality = " + q + " AND static = 0"
Die Zusatzbedingung static=0 verhindert, da das Referenzformat geloscht
wird.
Die DB2-Extender ermoglichen das Speichern der Bilder als Blobs in der Datenbank oder als Dateien im Filesystem. In dieser Implementierung wird die zweite
Variante verwendet, da etliche UDFs der DB2-Extender nur dann funktionieren. Nachteilig ist, da diese Funktionen zwar Dateien erzeugen konnen (z.B.
beim Einfugen neuer Attribute), diese aber nicht zu loschen vermogen. Dies
kann jedoch leicht von Java ubernommen werden, denn mit folgender kurzer
Anweisung kann die Datei geloscht werden, die in der Zeichenkette filename
(in der Form Pfad+Dateiname) steht:
File f1 = new File(filename)
f1.delete()
Der Dateiname eines Bildes kann beispielsweise mit der UDF filename der
DB2-Extender bestimmt werden. Ezienter ist jedoch folgendes Vorgehen: Beim
Erzeugen der Bilder werden bereits eindeutige und sinnvolle Dateinamen verteilt, die der Form "Bildname+Qualitatsstufe+.+Format\ genugen. Die Qualitat wird hier nicht in der Form 100, 75, 50, 25 sondern wegen besserer Lesbarkeit mit s1, s2, s3, s4 bezeichnet. Soll nun ein gewisses Attribut geloscht werden,
so kann mit Java leicht eine Liste der zugehorigen Dateien bestimmt und diese
geloscht werden. Dies geht naturlich wesentlich schneller als der hau
ge Zugri
auf die Datenbank.
Zum Einfugen neuer Bilder in die Datenbank braucht man die Dateinamen der
Bilder im Referenzformat und mu gema obigem Vorgehen Dateinamen fur die
neuen Bilder entwickeln. Lauten diese Dateinamen filename und filename_new
und soll das Bild mit der Bezeichnung name im Attribut a eingefugt werden, so
verwendet man folgendes Statement:
String sql = "INSERT INTO raw_image VALUES("+
"mmdbsys.DB2Image(CURRENT SERVER,"+
"CAST('"+filename+"' AS LONG VARCHAR),"+
"CAST('"+static_format+"' AS VARCHAR(8)),"+
"CAST('"+a.format+"' AS VARCHAR(8)),"+
"CAST('"+option+"' AS VARCHAR(100)),"+
"CAST('"+filename_new+"' AS LONG VARCHAR),''),"'+
name+"',"+a.quality+",0)"
4.3 Die Implementierung der Klassen
52
Hierbei gibt option die Skalierung in der Form -s x an, wobei x=1 beispielsweise 100% und x=0.75 einer 75%-Auosung entspricht. Die Typumwandlungen
sind notwendig, da die UDFs nur Parameter im korrekten Datentyp akzeptieren.
In der Tabelle conversion mu die Menge der zulassigen Konvertierungen angepat werden. Dazu wird zunachst fur alle Konvertierungen is_allowed=0
gesetzt:
String sql = "UPDATE conversion SET is_allowed=0"
Um die Konvertierungsregeln von Seite 10 zu erfullen, mu fur jedes gespeicherte
Attribut a, dessen Format nicht EPS, EP2, PS, PSC oder PS2 ist, das Attribut
b 2 Aphys mit der n
achstschlechteren Qualitat min bestimmt werden. Falls es
kein solches b gibt, so sei min=0. Aus a werden dann die Attribute berechnet,
deren Auosung besser als min ist:
String sql = "UPDATE conversion SET is_allowed = 1 WHERE " +
"source_format = '" + a.format + "' AND " +
"source_quality = " + a.quality + " AND " +
"target_format = '" + a.format + "' AND " +
"target_quality <= " + a.quality + " AND " +
"target_quality > " + min
Die ubrigen Attribute a 2 Acomp werden aus dem Referenzformat erzeugt:
String sql = "UPDATE conversion SET is_allowed = 1 WHERE " +
"source_format = '" + static_format + "' AND " +
"source_quality = " + static_quality + " AND " +
"target_format = '" + a.format + "' AND " +
"target_quality = " + a.quality
Schlielich mu noch die Tabelle query_profile aktualisiert werden: Das Alter
der Anfragen (Spalte age) wird inkrementiert. Wird das Hochstalter u berschritten, dann werden die entsprechenden Daten geloscht.
String sql = "UPDATE query_profile SET age = age + 1"
String sql2 = "DELETE FROM query_profile WHERE age >= " + q
4.3.3. Die Klasse Opti
Zur Kon
guration und Durchfuhrung der Optimierungen stellt diese Klasse eine
graphische Oberache zur Verfugung. Die Parameter werden wie im Kapitel 3
verwendeten Programm Scenery.java gesetzt. Naturlich wird hier kein Anfragepro
l eingegeben, da dies den statistischen Daten der Tabelle query_profile
entnommen wird. Das Textfeld dient der Ausgabe von Statusinformationen.
Nach der Optimierung wird in einem kleinen Fenster abgefragt, ob die Datenbank aktualisiert werden soll oder nicht. Dies ermoglicht den Ablauf mehrerer
4.4 SQL-Fehler und Java-Ausnahmen
53
Optimierungen (z.B. um verschiedene Parameterkombinationen zu testen) ohne
das zeitraubende Loschen und Einfugen von Bildern.
Abbildung 4.3 zeigt die Oberache nach einer Optimierung, die Ergebnisse sind
im Textfeld zu sehen. Wird im Question-Fenster "Yes\ angeklickt, so wird die
Datenbank aktualisiert, andernfalls ist der Lauf beendet.
Abbildung 4.3.: Benutzerschnittstelle
Die zugrundeliegende Bilddatenbank ist das im Abschnitt 1.3 vorgestellte Beispiel.
4.4. SQL-Fehler und Java-Ausnahmen
Fur das Versagen von SQL-Statements kann es verschiedene Ursachen geben,
z.B.:
♦
Der Datenbankserver wurde herunterge
4.4 SQL-Fehler und Java-Ausnahmen
54
Die angefragten Tabellen oder Spalten
Die Zugrisrechte reichen nicht aus.
ur die Ergebnismengen ist zu gering. Der Zwischenspeicher f
...
♦
♦
♦
♦
Bei Verwendung der DB2-Extender kann es noch weitere Probleme geben:
♦
♦
♦
♦
abled\).
Der Extender-Server ist heruntergefahre
ur die Extender freigegeben
Die Tabellen
("en- oder Spalten sind nicht f
ur die UDFs reicht nicht aus.
Der Speicher f
...
Java ermoglicht die komfortable Behandlung von Ausnahmesituationen (sog.
Exceptions). Kritische Anweisungen wie z.B. SQL-Statements konnen in einem
try-Block ausgef
uhrt werden. Treten dann Fehler auf, so wird ein Objekt eines
Ausnahmetyps (z.B. SQLException) erzeugt und die Anweisungen des catchBlocks ausgefuhrt, z.B.:
String sql = "UPDATE conversion SET is_allowed = 0"
Statement stmt
try
{
stmt = con.createStatement()
stmt.executeUpdate(sql)
stmt.close()
} catch (SQLException x)
{
System.out.println("Error in method update_conversion\n"+
+"while updating table conversion\n"+
+x.getMessage()
}
Die Methode x.getMessage() gibt die SQL-Fehlermeldung als String zuruck.
Im obigen Beispiel erfolgt die Ausgabe in der Shell, naturlich kann sie auch in
einem Textfeld einer GUI gezeigt werden.
5. Kritische Anmerkungen zu den
DB2-Extendern
Bei der Implementierung traten hau
g Schwierigkeiten mit den DB2-Extendern
auf. Typische Probleme, Software-Bugs und Fehler in der Dokumentation Ext]
sollen hier nun erlautert werden. Dies dient nicht der Abwertung der DB2Extender, sondern ist als Hilfestellung fur andere User gedacht, die zukunftig
mit dieser Software arbeiten.
Da die DB2-Extender mit groen Datenmengen arbeiten, treten hau
g Speicherprobleme auf. Diese konnen leicht behoben werden, indem die entsprechenden DB-Umgebungsvariablen geeignet gesetzt werden. Folgende Modi
kationen
haben sich als ausreichend erwiesen:
Variable
Beschreibung
Default Neu Einheit
aslheapsz
Heap-Speicher fur Programme
15
1000 4 KB
query_heap_sz Heap-Speicher f
ur Querys
1000 5000 4 KB
udf_mem_sz
Speicher fur Datentransfer
256 1024 4 KB
UDF $ Datenbank
Gesetzt werden sie im sog. Command-Line-Prozessor (CLP) mit folgender Anweisung:
UPDATE DBM CFG variable wert
Die Werte aller Variablen konnen mit GET DBM CFG angezeigt werden. Naheres
ndet sich in der Dokumentation von IBM (Com]).
In der Dokumentation der DB2-Extender traten folgende Unstimmigkeiten auf:
♦
♦
♦
nicht DB2IMAGE (bzw.BeiDB2AUDIO
der UDF content wird als
"handle\
oder DB2VIDEO) angegeben, sondern
der Name der Spalte vom Datentyp
DB2Image (DB2Audio, DB2Video).
Im Gegensatz zur Beschreibung darf d
Konvertierung sein.
ussen kleingeschrieDie Postscript-Formate EPS, EP2, PS,
ben werden, die anderen Formate werden grogeschrieben.
56
Beispiel:
SELECT DISTINCT name FROM raw_image
WHERE mmdbsys.format(ext_image)='GIF' OR
mmdbsys.format(ext_image)='ps'
Unschon ist auch, da Bilder in Postscript-Formaten nicht skaliert werden
konnen (weder mit der UDF content noch mit db2image). Auch dies wird
in der Dokumentation nicht erwahnt.
Ein weiterer Schwachpunkt ist, da die Funktion db2image Skalierungen nur
mit gleichzeitiger Formatumwandlung erlaubt. Sollen beispielsweise die Bilder
im Referenzformat zusatzlich in einer schwacheren Qualitat gespeichert werden
(als Ergebnis einer Optimierung), so mussen die Bilder mit der UDF content
skaliert und temporar gespeichert werden und konnen erst dann mit db2image
in die Datenbank eingefugt werden. Mit content ist u brigens das Skalieren
ohne Konvertierung moglich. Auch diese Anomalie ist es nicht wert, in der
Dokumentation erwahnt zu werden.
Schlielich erlauben die DB2-Extender pro Tabelle nur eine Spalte des Datentyps DB2Image. Dies war in dieser Arbeit kein Problem, konnte aber fur andere
Anwendungen durchaus eine enorme Einschrankung darstellen. U.U. kann dies
zu einem unnotigen und inezienten Splitting von Datenbanktabellen fuhren,
die bei Querys durch teure Joins wieder zusammengefuhrt werden mussen.
Die hier aufgefuhrten De
zite der DB2-Extender kosteten bei der Implementierung viel Zeit. Es ware zu wunschen, da IBM in zukunftigen Versionen oder
Fixpacks diese Probleme lost oder zumindest die Dokumentation etwas praziser
und ausfuhrlicher gestaltet.
6. Resumee und Ausblick
Die Zahl der Benutzer im Internet wachst stetig an, ein Ende ist nicht abzusehen. Die entsprechend hohe Netzlast reduziert die Transfergeschwindigkeit, so
da die Anzeige oder das Download von Daten hau
g zu einer Geduldsprobe
fur den User wird.
Gangige Methoden, dieses Problem zu mildern, sind:
♦
♦
♦
lation neuer Hochgeschwindigkeitsleitungen
den langsamen Transatlantik-Datenverkehr zu umgehen
Proxyserver
Verbesserung der Hardwarevoraussetzun
Spiegelung von Webservern an geograph
Verwendung einer intelligenten Cacheve
In dieser Arbeit wurde ein erganzender Ansatz gewahlt: Dokumente sollen
in verschiedenen Qualitatsstufen angeboten werden, denn zum Durchbrowsen
genugen dem Benutzer meist schwache Auosungen (geringe Groe, kaum Netzbelastung, kurze Ladezeiten). Interessiert er sich fur einen Artikel genauer, so
kann dieser dann in besserer Qualitat angezeigt werden.
Der Web- bzw. Datenbankserver mu die Dokumente also in verschiedenen Qualitatsstufen bereitstellen. Aufgrund der Heterogenitat der verwendeten Hard(ISDN, Modem, LAN usw.) und Software (z.B. unterschiedliche Browser, Viewer und Player) sollten insbesondere Multimediadokumente auch in verschiedenen Formaten zur Verfugung stehen. Da aber die Speicherung aller Formate
und Auosungen zu einem enormen Speicherbedarf fuhren kann, mu zwischen
zu speichernden und zu konvertierenden Formaten und Qualitaten entschieden
werden. Dazu wurden in dieser Arbeit Algorithmen implementiert und ausfuhrlich getestet. Die Szenarien verdeutlichten, da bereits durch geringen Speichermehraufwand auf der Benutzerseite viel Zeit eingespart werden kann. Dadurch
konnen auch die Betriebskosten von Unternehmen gesenkt werden, da die Mitarbeiter weniger Arbeitszeit zum Herunterladen von Multimendiadokumenten
benotigen.
Das verwendete Kostenmodell ist der Realitat bereits recht gut angepat: Festplattenkosten, Datentransferraten und Konvertierungszeiten gehen direkt in das
Modell ein.
58
Die moglichen Formate hangen von der verwendeten Software ab: Die DB2Extender unterstutzen 14 meist gangige Formate (siehe Seite 3). Dies reicht sicher fur viele Anwendungen aus, ist aber naturlich bei weitem nicht vollstandig.
Insbesondere ist bedauerlich, da das Format PNG (portable network graphics),
dessen Bedeutung im Internet stetig wachst, noch nicht zur Verfugung steht.
Moglicherweise stellt IBM in zukunftigen Versionen der DB2-Extender noch
mehr Formate bereit.
Falls man nicht solange warten will, hat man die Moglichkeit, zusatzliche Konvertierungstools zu verwenden. Fur die Optimierung macht dies keinen Unterschied, da dafur lediglich die Dauer der Formatumwandlung relevant ist.
Trotzdem muten etliche Anpassungen vorgenommen werden:
1. Die Tabelle raw_image braucht eine zusatzliche Spalte (Datentyp: Blob),
da unter ext_image nur von den DB2-Extendern unterstutzte Formate
verwaltet werden konnen.
2. In conversion ist eine zusatzliche Spalte notig, die angibt, von welchem
Tool die jeweilige Konvertierung durchzufuhren ist.
3. Das Einfugen der Bilder in neuen Formaten erfordert eine Anpassung der
Methode insert_raw_image der Klasse Optimization: Statt der UDF
db2image mu hier das zus
atzliche Konvertierungstool und dessen Syntax
berucksichtigt werden.
Der Einsatz zusatzlicher Formate erfordert also nur geringe Mehrarbeit. Trotzdem sollte dies aus Performancegrunden soweit wie moglich vermieden werden,
denn zum einen entsteht ein zusatzlicher Verwaltungsaufwand (Erweiterung
der Tabellen und des Quellcodes), zum andern fuhren die zusatzlichen Funktionen zu erhohtem Rechen- und Speicherbedarf. Die UDFs der DB2-Extender
konnen hingegen auf einem vom Datenbanksystem speziell fur UDFs angelegten Speicherbereich ausgefuhrt werden, so da hier kein zusatzlicher Speicher
belegt wird.
In dieser Arbeit wurde speziell die Formatoptimierung fur Bilder implementiert.
Fur Audio- und Videodaten ist ein analoges Vorgehen moglich: Auch hier gibt
es verschiedene Formate, die Qualitat wird hier aber nicht durch die Auosung,
sondern durch die Samplingrate (in Samples
sec ) bestimmt.
Zukunftige Internet-Standards wie XML1 (Extensible Markup Language) in
Verbindung mit XSL2 (Extensible Stylesheet Language) und CSS3 (Cascading
Style Sheets) unterstutzen zunehmend die Trennung semantischer Inhalte der
Web-Seiten von ihrer Display-Information. Insbesondere hier entstehen neue
Einsatzfelder fur (selbst-optimierende) Multimedia-Datenbanksysteme.
http://www.w3.org/xml/
http://www.w3.org/style/xsl/
3
http://www.w3.org/style/css/
1
2
A. Shell-Skripte
Diese Programme dienen dem einfachen Anlegen und Fullen der von der Optimierung benotigten Tabellen. Sie konnen bei Bedarf aus dem Internet1 runtergeladen werden.
A.1. Anlegen der Tabellen
Dieses Programm legt die Datenbanktabellen an, die dazugehorige Datei heit
create tables.sql.
#! /bin/ksh
#################################################
# This shell-script creates tables for the
# optimization
#
# creating the tables image, raw_image,
# query_profile, conversion, optimization
#
#################################################
# connect to the database stefandb
db2 connect to stefandb
# delete existing tables
db2 drop table image
db2 drop table raw_image
db2 drop table query_profile
db2 drop table conversion
db2 drop table opti_log
### image:
### -----db2 create table image\
"("\
name
varchar"("100")" primary key not null,\
description
varchar"("1000")"\
")"
### raw_image:
### ---------db2 create table raw_image\
"("\
1
http://heron.informatik.uni-augsburg.de/tmplobs/doc/main.htm
A.1 Anlegen der Tabellen
ext_image
mmdbsys.db2image primary key not null,\
name
varchar"("100")",\
quality
integer,\
static
integer,\
foreign key "("name")" references image\
")"
### conversion:
### ----------db2 create table conversion\
"("\
source_format
varchar"("10")" not null,\
source_quality
integer not null,\
target_format
varchar"("10")" not null,\
target_quality
integer not null,\
z_hist
double,\
avg_conv_time
integer,\
is_allowed
integer,\
primary key "("source_format,target_format,\
source_quality,target_quality")"\
")"
### query_profile:
### -------------db2 create table query_profile\
"("\
date_time
timestamp primary key not null,\
name
varchar"("100")",\
source_format
varchar"("10")" ,\
source_quality
integer,\
target_format
varchar"("10")" ,\
target_quality
integer,\
target_image_sz
integer,\
conv_time
integer,\
age
integer,\
foreign key "("name")" references image,\
foreign key "("source_format,target_format,\
source_quality,target_quality")" \
references conversion\
")"
### opti_log:
### ------------db2 create table opti_log\
"("\
date_time
timestamp primary key not null,\
static_format
varchar"("10")",\
z
double,\
c_s
double,\
c_a
double,\
c_c
double,\
p
int,\
q
int,\
number_of_images
int,\
hd_size
varchar"("50")",\
hd_cost
varchar"("50")",\
60
A.2 Einfugen der Bildinformation (gekurzt)
comp_time
total_time
acc_cost_preopt
store_cost_preopt
acc_cost_saveall
store_cost_saveall
acc_cost_saveno
store_cost_saveno
acc_cost_opt
store_cost_opt
a_phys
")"
61
int,\
int,\
int,\
int,\
int,\
int,\
int,\
int,\
int,\
int,\
varchar"("450")"\
# disconnect all
db2 connect reset
# enable tables and columns for the DB2-Extenders
db2ext connect to stefandb
db2ext enable table raw_image for db2image
db2ext enable column raw_image ext_image for db2image
db2ext connect reset
### end of file
A.2. Einfugen der Bildinformation (gekurzt)
Hier wird die Tabelle image mit Name und Beschreibung der Bilder gefullt. Die
Datei heit insert image.sql.
#! /bin/ksh
################################################
#
# Shell-script for inserting the hagar-data
# into the table image
#
################################################
# connect to stefandb
db2 connect to stefandb
# delete existing rows
db2 delete from image
# insert new rows
db2 insert into image values \
"(""'"achtzehn"'","'"Ach ja, ich war auch schon mal Achtzehn..."'"")",\
"(""'"achten"'","'"Es ist nicht so schlimm...Aber achte einige Tage \
darauf, was Du isst"'"")",\
.
.
.
A.3 Einfugen der Bilder (gekurzt)
62
"(""'"wollschmetterling"'","'"Ein harter Winter"'"")",\
"(""'"zapfhahn"'","'"He, Haegar! Sieh Dir das mal an!"'"")"
# disconnect
db2 connect reset
# end of file
A.3. Einfugen der Bilder (gekurzt)
Zum Einfugen der Bilder in die Tabelle raw image wird die UDF
benotigt. Die auszufuhrende Datei heit insert_raw_image.sql.
#! /bin/ksh
################################################
#
# Shell-script for inserting the hagar-pictures
# into the table raw_image
#
################################################
# connect to stefandb
db2 connect to stefandb
# delete existing rows
db2 delete from raw_image
# insert new rows
db2 insert into raw_image values \
"("mmdbsys.DB2Image"("CURRENT SERVER,"'"/home/db2inst3/\
DA/image/static_raw_image/achtzehn.gif"'",\
"'"ASIS"'",0,"'" "'"")","'"achtzehn"'",100,1")"
db2 insert into raw_image values \
"("mmdbsys.DB2Image"("CURRENT SERVER,"'"/home/db2inst3/\
DA/image/static_raw_image/achten.gif"'",\
"'"ASIS"'",0,"'" "'"")","'"achten"'",100,1")"
.
.
.
db2 insert into raw_image values \
"("mmdbsys.DB2Image"("CURRENT SERVER,"'"/home/db2inst3/\
DA/image/static_raw_image/wollschmetterling.gif"'",\
"'"ASIS"'",0,"'" "'"")","'"wollschmetterling"'",100,1")"
db2 insert into raw_image values \
"("mmdbsys.DB2Image"("CURRENT SERVER,"'"/home/db2inst3/\
DA/image/static_raw_image/zapfhahn.gif"'",\
"'"ASIS"'",0,"'" "'"")","'"zapfhahn"'",100,1")"
# disconnect
db2 connect reset
# end of file
db2image
B. Programmcode
In diesem Kapitel werden die Quelltexte aufgelistet. Sie konnen auch aus dem
Internet1 runtergeladen werden.
B.1. Die Webseite
An die Hagar-Datenbank konnen u ber das Internet2 Anfragen gestellt werden.
Zur Erstellung der Webseite wurde das Tool Net.Data3 von IBM verwendet.
%{
**************************************************************************
Define Section: Use this section to define variables (e.g.
DATABASE) used in your macro file. At a minimum, the DATABASE
variable must be defined.
**************************************************************************
%}
%DEFINE{
DATABASE="stefandb"
SHOWSQL="NO"
get_image= %EXEC "/home/db2inst4/bin/image2file $(name) $(format) $(scal)"
%}
%{
**************************************************************************
Function query: Use this section to define SQL queries.
**************************************************************************
%}
%FUNCTION(DTW_SQL) query1() {
select name,description from db2inst4.image
%REPORT{
%ROW{
<dd><input type="radio" name="name" value="$(V1)"> $(V2)
%}
%}
%}
%{
**************************************************************************
INPUT Section: Use this section to specify the page (in HTML) to
http://heron.informatik.uni-augsburg.de/tmplobs/doc/main.htm
http://heron.informatik.uni-augsburg.de/db2www-bin/db2www/da1 net.d2w/input
3
http://www.software.ibm.com/data/net.data
1
2
B.1 Die Webseite
be used to collect information from the user to be used in the
query. Note how the value of ACTION specifies the report section
of this macro file. When the user selects the "Submit Query"
button, the REPORT section specified below will be processed.
**************************************************************************
%}
%HTML(INPUT){
<HTML>
<HEAD>
<TITLE>The big Hagar collection</TITLE>
</HEAD>
<BODY BACKGROUND="/pictures/tan_paper.gif">
<p>
<H1> Querying the HAGAR-database </H1>
<p>
<hr>
<FORM METHOD="POST"
ACTION="/db2www-bin/db2www/da1_net.d2w/report">
First, choose a picture ...
<p>
<dl>
@query1()
</dl>
<p>
<hr>
... then select a format ...
<p>
<dd><input type="radio" name="format" value="BMP">
BMP: Microsoft Windows bitmap
<dd><input type="radio" name="format" value="eps">
EPS: Encapsulated PostScript
<dd><input type="radio" name="format" value="ep2">
EP2: Encapsulated level 2 PostScript
<dd><input type="radio" name="format" value="GIF">
GIF: Compuserve GIF89a and 87
<dd><input type="radio" name="format" value="IMG">
IMG: IOCA Image
<dd><input type="radio" name="format" value="IPS">
IPS: Brooktrout FAX card file
<dd><input type="radio" name="format" value="JPG">
JPG: JPEG(3)
<dd><input type="radio" name="format" value="PCX">
PCX: PC paint file
<dd><input type="radio" name="format" value="PGM">
PGM: Portable gray map
<dd><input type="radio" name="format" value="ps">
PS: PostScript
<dd><input type="radio" name="format" value="psc">
PSC: Compressed PostScript image
<dd><input type="radio" name="format" value="ps2">
PS2: PostScript level 2
<dd><input type="radio" name="format" value="TIF">
TIF: All TIFF 5.0 formats
<dd><input type="radio" name="format" value="YUV">
YUV: Digial video for YUV
64
B.2 Das CGI-Programm
65
<p>
<hr>
... and the scaling factor ...
<p>
<dd><input type="radio" name="scal" value="s1"> 100 %
<dd><input type="radio" name="scal" value="s2"> 75 %
<dd><input type="radio" name="scal" value="s3"> 50 %
<dd><input type="radio" name="scal" value="s4"> 25 %
<p>
<hr>
... and finally klick on the "Submit"-Button.
<hr>
<INPUT TYPE="submit" VALUE="Submit">
</FORM>
</BODY>
</HTML>
%}
%{
**************************************************************************
REPORT Section: Use this section to specify the page (in HTML) to
be seen after the SQL queries are executed.
**************************************************************************
%}
%HTML(REPORT){
$(get_image)
<HTML>
<HEAD>
<TITLE>Show the selected hagar picture</TITLE>
</HEAD>
<BODY BACKGROUND="/pictures/tan_paper.gif">
Please klick <a href="/tmplobs/$(name)$(scal).$(format)">here</a>.
</BODY>
</HTML>
%}
B.2. Das CGI-Programm
Zur Formatkonvertierung und Skalierung verwendet die Webseite das CGIProgramm image2file (Dateiname image2file.sqc). Hier werden auch die
Anfragen registriert und damit die Tabelle query_profile gefullt.
#include <stdio.h>
#include <string.h>
#include <sqlenv.h>
int main(int argc, char *argv ])
{
EXEC SQL INCLUDE SQLCA
EXEC SQL BEGIN DECLARE SECTION
char dbname 10] = "stefandb"
B.2 Das CGI-Programm
char
char
char
char
char
name 100]
filename 100] =
*name_pointer =
*format_pointer
*scal_pointer =
66
"/usr/local/apache/htdocs/tmplobs/"
argv 1]
= argv 2]
argv 3]
char target_format 10]
short target_quality
long target_image_size
char scal 10]
char msgbuffer 500]
SQL TYPE IS BLOB_FILE newpicture
char source_format 10],sf 10]
short source_quality,sq
long source_image_size = 0
char dat_tim1 26]
char dat_tim2 26]
long timdif1, timdif2, timdif
char command 30] = "chmod a+r "
short i
EXEC SQL END DECLARE SECTION
EXEC SQL WHENEVER SQLERROR GO TO badnews
/**** get the parameters name, format, scal ****/
i=0
do
{
name i]=*name_pointer
name_pointer++
i++
}
while(*name_pointer!='\0')
name i]='\0'
i=0
do
{
target_format i]=*format_pointer
format_pointer++
i++
}
while(*format_pointer!='\0')
target_format i]='\0'
scal 0]=*scal_pointer
scal 1]=*(scal_pointer+1)
scal 2]='\0'
/**** create the filename and prepare the newpicture-variable
strcat(filename,name)
strcat(filename,scal)
strcat(filename,".")
strcat(filename,target_format)
strcpy(newpicture.name,filename)
****/
B.2 Das CGI-Programm
67
newpicture.name_length = strlen(newpicture.name)
newpicture.file_options = SQL_FILE_OVERWRITE
if
if
if
if
(strcmp(scal,"s1")==0)
(strcmp(scal,"s2")==0)
(strcmp(scal,"s3")==0)
(strcmp(scal,"s4")==0)
target_quality
target_quality
target_quality
target_quality
=
=
=
=
100
75
50
25
putenv("DB2INSTANCE=db2inst4")
EXEC SQL CONNECT to :dbname
EXEC SQL SELECT DISTINCT CURRENT TIMESTAMP
INTO :dat_tim1 FROM db2inst4.image
/**** get the picture without conversion if possible ****/
EXEC SQL SELECT mmdbsys.content(ext_image), mmdbsys.format(ext_image),
mmdbsys.size(ext_image),quality
INTO :newpicture, :source_format,
:source_image_size, :source_quality
FROM db2inst4.raw_image
WHERE name = :name AND quality = :target_quality
AND mmdbsys.format(ext_image) = :target_format
target_image_size = source_image_size
i = 0
/**** else convert the picture ****/
if(source_image_size == 0)
{
EXEC SQL SELECT source_format, source_quality
INTO :sf, :sq
FROM db2inst4.conversion
WHERE target_format = :target_format
AND target_quality = :target_quality AND is_allowed=1
/**** compute the right scaling factor ****/
if(sq == 100)
{
if(target_quality == 100) strcpy(scal,"-s 1.0")
else if(target_quality == 75) strcpy(scal,"-s 0.75")
else if(target_quality == 50) strcpy(scal,"-s 0.50")
else strcpy(scal,"-s 0.25")
}
else if(sq == 75)
{
if(target_quality == 75) strcpy(scal,"-s 1.0")
else if(target_quality == 50) strcpy(scal,"-s 0.67")
else strcpy(scal,"-s 0.33")
}
else if(sq == 50)
{
if(target_quality == 50) strcpy(scal,"-s 1.0")
else strcpy(scal,"-s 0.5")
}
else strcpy(scal,"-s 1.0")
EXEC SQL SELECT mmdbsys.content(ext_image, :target_format, :scal),
B.3 Java und JDBC Programme
68
mmdbsys.format(ext_image), mmdbsys.size(ext_image), quality
INTO :newpicture, :source_format,
:source_image_size, :source_quality
FROM db2inst4.raw_image
WHERE name = :name AND quality = :sq
AND mmdbsys.format(ext_image) = :sf
target_image_size = newpicture.data_length
i = 1
}
EXEC SQL SELECT DISTINCT CURRENT TIMESTAMP
INTO :dat_tim2 from db2inst4.image
/**** get the duration for the conversion ****/
EXEC SQL SELECT DISTINCT
minute(:dat_tim1)*60000+second(:dat_tim1)*1000+
trunc(microsecond(:dat_tim1)/1000,0),
minute(:dat_tim2)*60000+second(:dat_tim2)*1000+
trunc(microsecond(:dat_tim2)/1000,0)
INTO :timdif1,:timdif2 FROM db2inst4.image
timdif=i*(timdif2-timdif1)
strcat(command,filename)
system(command)
/*** put the data into the table "query_profile" ***/
EXEC SQL INSERT INTO db2inst4.query_profile VALUES(
CURRENT TIMESTAMP, :name, :source_format,
:source_quality, :target_format, :target_quality,
:target_image_size, :timdif,0)
EXEC SQL COMMIT
EXEC SQL CONNECT RESET
return 0
badnews:
printf("Unexpected return code from DB2. \n")
sqlaintp(msgbuffer, 500, 70, &sqlca)
printf("Message: %s\n",msgbuffer)
return 0
}
B.3. Java und JDBC Programme
In diesem Abschnitt werden die Java-Quellcodes der Klassen Attribut und
Optimization aufgelistet. Diese und die u
brigen Klassen nden sich auch im
Internet4 .
4
http://heron.informatik.uni-augsburg.de/tmplobs/doc/main.htm
B.3 Java und JDBC Programme
B.3.1.
Attribut.java
Attribute werden in einer eigenen Klasse abgelegt.
/**
* class Attribut contains data about the attributes
*/
public class Attribut
{
/**
* format of the attribut
*/
protected String format
/**
* quality of the attribut
*/
protected int quality
/**
* avg_image_size <= 2 GB
*/
protected int avg_image_size
/**
* 0 <= avg_acc <= 1
*/
protected double avg_acc
/**
* bit_used = 1 if the set of the physical stored attributs
* during the current optmization step contains this attribut
* else bit_used = 0
*/
protected int bit_used
/**
* bit_best = 1 for the optimal set
* of physical stored attributs
*/
protected int bit_best
/**
* access cost of this attribut
*/
protected double acc_cost
/**
* avg_conv_time contains the
* converting duration from the static_format
* (avg_conv_time 0]), and from the "better"
* formats to this format, e.g. if attribut = GIF50
* then avg_conv_time 1] is the duration of
* GIF100 -> GIF50 and avg_conv_time 2] is the time for
* GIF75 -> GIF50
*/
protected int ] avg_conv_time
69
B.3 Java und JDBC Programme
/**
* constructor for an attribut, it's used by
* the class Optimization
*/
protected Attribut(String form,int qual, int size, double avg_a)
{
format = form
quality = qual
avg_image_size = size
avg_acc = avg_a
bit_used = 0
bit_best = 0
avg_conv_time = new int 4]
} // End of construktor
/**
* test if two attributs are equal
*/
protected boolean equals(Attribut a)
{
if((format.compareTo(a.format)==0) && (quality == a.quality))
return true
else return false
} // end of method equals
} // end of class Attribut
B.3.2.
Optimization.java
In diesem Programm ndet die eigentliche Optimierung statt.
import java.io.*
import java.util.*
import java.sql.*
/**
* the class Optimization contains the optimization algorithm
*/
public class Optimization
{
/**
* z is the weight of the acc_cost and (1-z) is the weight of
* store_cost
*/
public double
z
/**
* c_s is the factor of the store_cost
* (only relevant if use_stepfunction = false)
*/
public double
c_s
/**
* c_a is the factor of the acc_cost for physical stored attributes
70
B.3 Java und JDBC Programme
*/
public double
c_a
/**
* c_c is the factor of the avg_conv_time
*/
public double
c_c
/**
* p is the minimal number of requests for an
* attribut that should be relevant for the optimization
*/
public int p
/**
* q is the maximal number of optimization runs for
* each entry in the query_profile
*/
public int q
/**
* if use_total_access = false than the average access rate
* is the weight of the access costs
* else the total number of accesses is used
*/
public boolean use_total_access
/**
* if use_total_store = true the total used storage of
* all physical saved attributes is relevant,
* else the optimization algorithm uses just
* the average used storage of each attribute
*/
public boolean use_total_store
/**
* if use_stepfunction = true then the parameters
* hd_size and hd_cost are used else the paramter
* c_s is used
*/
public boolean use_stepfunction
/**
* hd_size are the sizes (MB) of the hard disks
* (only used if use_stepfunction = true)
*/
public int ] hd_size
/**
* hd_cost are the costs for each hd_disk
* (only used if use_stepfunction = true)
*/
public int ] hd_cost
// variables for the static attribut
private String static_format
71
B.3 Java und JDBC Programme
private int static_quality = 100
private int static_acc_cost
// number of images
private int num
// variables for the costs
private int cost_pre_opt, cost_post_opt, cost_save_all, cost_save_no
private int store_cost_pre_opt, store_cost_post_opt
private int store_cost_save_all, store_cost_save_no
private int acc_cost_pre_opt, acc_cost_post_opt
private int acc_cost_save_all, acc_cost_save_no
// variable for the optimization time (ms)
private int comp_time
// variable for the total time (including image conversion)
private int total_time
// list for the attributs
private Vector attribut_list = new Vector()
// list for A_phys
private Vector a_phys_list = new Vector()
// strings for error messages and result
private String error = "", result
static
{
try
{
Class.forName("COM.ibm.db2.jdbc.app.DB2Driver")
} catch ( ClassNotFoundException x )
{
System.out.println("\nERROR loading DB2-Driver")
x.printStackTrace()
}
}
/**
* this is a constructor for Optimization objects,
* it's used by the class Opti
*/
public Optimization(double z1, double c_s1, double c_a1,
double c_c1, int min, int max,
int ] hs, int ] hc,
boolean total, boolean use_hd,
boolean total_acc)
{
z = z1
c_s = c_s1
c_a = c_a1
c_c = c_c1
p = min
72
B.3 Java und JDBC Programme
q = max
hd_size = hs
hd_cost = hc
use_total_store = total
use_stepfunction = use_hd
use_total_access = total_acc
}
/*
* this method prepares the statistical data and
* runs the optimization algorithm
*/
public String start(Opti caller)
{
Connection con
try
{
con = DriverManager.getConnection("jdbc:db2:stefandb")
// preparing ...
caller.output.setText("preparing data ... ")
total_time = (int)System.currentTimeMillis()
get_static_attribut(con)
update_conversion1(con)
get_attributs(con)
update_attributs(con)
update_query_profile(con)
caller.output.appendText("done\n")
con.close()
}catch(SQLException x)
{
error +=
"\nERROR(method start): getConnection to stefandb \n"+
x.getMessage()
}
// computing ...
comp_time = (int)System.currentTimeMillis()
caller.output.appendText("computing ... ")
optimization_algorithm()
caller.output.appendText("done")
comp_time = (int)System.currentTimeMillis() - comp_time
result="\nresult:\n=======\n\nacc_cost_pre_opt: "+acc_cost_pre_opt+
"\nstore_cost_pre_opt: "+store_cost_pre_opt+"\ncost_pre_opt: "+
cost_pre_opt+
"\n\nacc_cost_save_all: "+acc_cost_save_all+
"\nstore_cost_save_all: "+store_cost_save_all+"\ncost_save_all: "+
cost_save_all+
"\n\nacc_cost_save_no: "+acc_cost_save_no+
"\nstore_cost_save_no: "+store_cost_save_no+"\ncost_save_no: "+
cost_save_no+
"\n\nacc_cost_post_opt: "+acc_cost_post_opt+
"\nstore_cost_post_opt: "+store_cost_post_opt+"\ncost_post_opt: "+
cost_post_opt+"\n\n"
int i = 0
while(i < attribut_list.size())
73
B.3 Java und JDBC Programme
{
Attribut a = (Attribut)attribut_list.elementAt(i)
result += "\n"+a.format+a.quality+" is_saved: "+a.bit_best
i++
}
total_time = (int)System.currentTimeMillis() - total_time
if(error.compareTo("") == 0) return result
else return error
} // end of method start
/**
* this method updates the database, e.g.
* converting pictures, deleting attributs, ...
*/
public String update_database(Opti caller)
{
Connection con
try
{
total_time = total_time - (int)System.currentTimeMillis()
con = DriverManager.getConnection("jdbc:db2:stefandb")
caller.output.setText("\ndeleting images ... ")
delete_raw_image(con)
caller.output.appendText("done\ninserting pictures ... ")
insert_raw_image(con, caller)
caller.output.appendText("done\nupdating table conversion ... ")
update_conversion2(con)
caller.output.appendText("done\n")
total_time = (int)System.currentTimeMillis() + total_time
// store the optimization-log in the database
save_log(con)
con.close()
}catch(SQLException x)
{
error =
"\nERROR (method update database): getConnection to stefandb\n"+
x.getMessage()
}
if(error.compareTo("") != 0) return error
else return "Everything ok!"
} // end of method update_database
// get static_format and static_acc_cost
private void get_static_attribut(Connection con)
{
String sql =
"SELECT mmdbsys.format(ext_image),mmdbsys.size(ext_image) "+
"FROM raw_image WHERE static=1"
try
{
Statement stmt = con.createStatement()
ResultSet rs = stmt.executeQuery(sql)
74
B.3 Java und JDBC Programme
num = 0
static_acc_cost = 0
while(rs.next())
{
static_format = rs.getString(1)
static_acc_cost += rs.getInt(2)
num++
}
static_acc_cost = (int)(c_a*(static_acc_cost/num))
rs.close()
stmt.close()
}catch(SQLException x)
{
error +=
"\nERROR (method get_static_attribut: "+
"SELECT ... static_acc_cost \n"+
x.getMessage()
}
} // end of method get_static_attribut
// update the conversion duration in the
// table conversion
private void update_conversion1(Connection con)
{
String sql =
"SELECT source_format, source_quality, "+
"target_format, target_quality, "+
"AVG(conv_time) FROM query_profile "+
"WHERE age = 0 AND conv_time > 0 "+
"GROUP BY source_format, source_quality, "+
"target_format, target_quality "
try
{
Statement stmt = con.createStatement()
ResultSet rs = stmt.executeQuery(sql)
while(rs.next())
{
sql =
"UPDATE conversion SET "+
"avg_conv_time = CAST((z_hist * avg_conv_time) + "+
"((1 - z_hist) * "+rs.getInt(5)+") AS INTEGER)"+
"WHERE source_format = '"+rs.getString(1)+"' "+
"AND source_quality = "+rs.getInt(2)+" "+
"AND target_format = '"+rs.getString(3)+"' "+
"AND target_quality = "+rs.getInt(4)
try
{
Statement stmt2 = con.createStatement()
stmt2.executeUpdate(sql)
stmt2.close()
}catch(SQLException x)
{
error +=
"\nERROR (method update_conversion1: "+
"UPDATE on conversion \n"+
x.getMessage()
75
B.3 Java und JDBC Programme
}
} // end of while(rs.next())
rs.close()
stmt.close()
}catch(SQLException x)
{
error +=
"\nERROR (method update_conversion1: "+
"SELECT on query_profile \n"+
x.getMessage()
}
} // end of method update_conversion1
// get the used attributs from the table query_profile
private void get_attributs(Connection con)
{
int acc_sum = 0
try
{
Statement stmt = con.createStatement()
String sql =
"SELECT target_format, target_quality, "+
"AVG(target_image_sz), count(*) "+
"FROM query_profile "+
"WHERE age < "+q+" "+
"GROUP BY target_format,target_quality "+
"HAVING count(*) >= " + p
ResultSet rs = stmt.executeQuery(sql)
while(rs.next())
{
String format = rs.getString(1)
int quality = rs.getInt(2)
// don't take the static_format
if((format.compareTo(static_format) != 0) ||
(quality != static_quality))
{
Attribut a = new Attribut(format,
quality,
rs.getInt(3),
(double)rs.getInt(4))
attribut_list.addElement(a)
acc_sum += a.avg_acc
}
}
rs.close()
stmt.close()
}catch(SQLException x)
{
error +=
"\nERROR (method get_attributs): "+
"SELECT on query_profile \n"+
x.getMessage()
}
if(!(use_total_access))
{
int i = 0
76
B.3 Java und JDBC Programme
while(i < attribut_list.size())
{
Attribut a = (Attribut)attribut_list.elementAt(i)
a.avg_acc /= acc_sum
i++
}
}
} // end of method get_attributs
// get converting times and avg_image_size
private void update_attributs(Connection con)
{
int i = 0
while(i < attribut_list.size())
{
Attribut a = (Attribut)attribut_list.elementAt(i)
String sql =
"SELECT avg_conv_time FROM conversion "+
"WHERE target_format='"+a.format+"' "+
"AND target_quality="+a.quality+" "+
"AND source_format='"+static_format+"' "+
"AND source_quality="+static_quality
try
{
Statement stmt = con.createStatement()
ResultSet rs = stmt.executeQuery(sql)
rs.next()
a.avg_conv_time 0] = rs.getInt(1)
rs.close()
stmt.close()
}catch(SQLException x)
{
error +=
"\nERROR (method update_attributs): "+
"SELECT on conversion (1)\n"+
x.getMessage()
}
sql =
"SELECT avg_conv_time, source_quality "+
"FROM conversion "+
"WHERE target_format='"+a.format+"' "+
"AND target_quality="+a.quality+" "+
"AND source_format='"+a.format+"' "+
"AND source_quality>"+a.quality+" "+
"ORDER BY source_quality DESC"
try
{
Statement stmt = con.createStatement()
ResultSet rs = stmt.executeQuery(sql)
int j = 1
while(rs.next())
{
a.avg_conv_time j] = rs.getInt(1)
j++
}
rs.close()
77
B.3 Java und JDBC Programme
stmt.close()
}catch(SQLException x)
{
error +=
"\nERROR (method update_attributs): "+
"SELECT on conversion (2)\n"+
x.getMessage()
}
i++
} // end of while(i < attribut_list.size())
String sql =
"SELECT DISTINCT mmdbsys.format(ext_image), "+
"quality FROM raw_image WHERE static = 0"
try
{
Statement stmt = con.createStatement()
ResultSet rs = stmt.executeQuery(sql)
while(rs.next())
{
String f = rs.getString(1)
int q = rs.getInt(2)
Attribut a = new Attribut(f,q,0,0)
a_phys_list.addElement(a)
i = 0
while(i < attribut_list.size())
{
Attribut b = (Attribut)attribut_list.elementAt(i)
if(((b.format).compareTo(f) == 0) &&
(b.quality == q))
{
sql =
"SELECT AVG(mmdbsys.size(ext_image)) "+
"FROM raw_image "+
"WHERE mmdbsys.format(ext_image)='"+
b.format+"' AND quality="+b.quality
try
{
Statement stmt2 = con.createStatement()
ResultSet rs2 = stmt2.executeQuery(sql)
rs2.next()
b.avg_image_size = (int)rs2.getDouble(1)
rs2.close()
stmt2.close()
b.bit_used = 1
}catch(SQLException x)
{
error +=
"\nERROR (method update_attributs): "+
"SELECT AVG on raw_image \n"+
x.getMessage()
}
}
i++
} // end of while(i < attribut_list.size())
} // end of while(rs.next())
rs.close()
stmt.close()
78
B.3 Java und JDBC Programme
}catch(SQLException x)
{
error +=
"\nERROR (method update_attributs): "+
"SELECT on raw_image \n"+
x.getMessage()
}
} // end of method update_attributs
// set age = age + 1 for each row in the query_profile
// and delete querys older than q
private void update_query_profile(Connection con)
{
String sql =
"UPDATE query_profile SET age = age + 1"
Statement stmt
try
{
stmt = con.createStatement()
stmt.executeUpdate(sql)
stmt.close()
}catch(SQLException x)
{
error +=
"\nERROR (method update_query_profile): "+
"UPDATE on query_profile \n"+
x.getMessage()
}
sql =
"DELETE FROM query_profile "+
"WHERE age >= "+q
try
{
stmt = con.createStatement()
stmt.executeUpdate(sql)
stmt.close()
}catch(SQLException x)
{
error +=
"\nERROR (method update_query_profile): "+
"DELETE on query_profile \n"+
x.getMessage()
}
} // end of method update_query_profile
// get each subset of the attributs
private boolean increment_attribut_list_bit_used()
{
int i = 0
int j = 0
try
{
while(i < attribut_list.size())
{
j = ((Attribut)attribut_list.elementAt(i)).bit_used %2
79
B.3 Java und JDBC Programme
((Attribut)attribut_list.elementAt(i)).bit_used = (j+1)%2
if(j == 0) break
i++
}
} catch (Exception x)
{
error +=
"\nERROR (method increment_attribut...): "+
"increment_attribut_list_bit_used \n"+
x.getMessage()
}
if(i == attribut_list.size()) return false
else return true
} // end of increment_attribut_list_bit_used
// compute the storage_cost
private double compute_store_cost()
{
int i = 0
double s_cost = 0
int hd_c = 0
try
{
while(i < attribut_list.size())
{
if(((Attribut)attribut_list.elementAt(i)).bit_used == 1)
{
if(use_total_store)
s_cost += num*
((Attribut)attribut_list.elementAt(i)).avg_image_size
else s_cost +=
((Attribut)attribut_list.elementAt(i)).avg_image_size
}
i++
}
if(use_stepfunction)
{
double size_mb = s_cost / 1000000
hd_c = hd_cost 0]
i = 0
while(true)
{
if(size_mb > hd_size i])
{
size_mb -= hd_size i]
if(hd_size i+1] > 0)
i++
hd_c += hd_cost i]
}
else break
}
if(s_cost == 0)
hd_c = 0
}
}catch(Exception x)
{
80
B.3 Java und JDBC Programme
error +=
"\nERROR (method compute_store_cost): "+
"compute_store_cost \n"+
x.getMessage()
}
if(use_stepfunction)
return(hd_c)
else return (c_s*s_cost)
} // end of method compute_store_cost
// compute the access_cost
private double compute_access_cost()
{
double a_cost = 0
try
{
// compute acc_cost(A), A is in A_phys
int i = 0
while(i < attribut_list.size())
{
Attribut a = (Attribut)attribut_list.elementAt(i)
a.acc_cost = a.bit_used * c_a * a.avg_image_size
i++
}
// compute acc_cost(A), A is in A_comp
i = 0
while(i < attribut_list.size())
{
Attribut a = (Attribut)attribut_list.elementAt(i)
if(a.bit_used == 0)
{
int j = 0,k = 0
String form = static_format
int qual = static_quality
while(j < attribut_list.size())
{
Attribut b = (Attribut)attribut_list.elementAt(j)
if((b.bit_used == 1) &&
((b.format).compareTo(a.format) == 0) &&
(b.quality <= qual) &&
(b.quality > a.quality))
{
form = b.format
qual = b.quality
k = j
}
j++
}
if((form.compareTo(static_format) == 0) ||
((a.format).compareTo("eps") == 0) ||
((a.format).compareTo("ep2") == 0) ||
((a.format).compareTo("ps") == 0) ||
((a.format).compareTo("psc") == 0) ||
((a.format).compareTo("ps2") == 0))
j = 0
else if(qual == 100) j = 1
81
B.3 Java und JDBC Programme
else if(qual == 75) j = 2
else if(qual == 50) j = 3
Attribut b = (Attribut)attribut_list.elementAt(k)
if(j == 0)
a.acc_cost = static_acc_cost + c_c * a.avg_conv_time j]
else a.acc_cost = b.acc_cost + c_c * a.avg_conv_time j]
}
i++
} // end of while(i < attribut_list.size())
// compute the acc_cost of all attributes
i = 0
while(i < attribut_list.size())
{
Attribut a = (Attribut)attribut_list.elementAt(i)
a_cost += a.acc_cost * a.avg_acc
i++
}
} catch(Exception x)
{
error +=
"\nERROR (method compute_access_cost): "+
"compute_acc_cost \n"+
x.getMessage()
}
return a_cost
} // end of method compute_access_cost
// the real optimization ...
private void optimization_algorithm()
{
try
{
// pre optimization costs
store_cost_pre_opt = (int)compute_store_cost()
acc_cost_pre_opt = (int)compute_access_cost()
cost_pre_opt = (int)((1-z)*compute_store_cost() +
z*compute_access_cost())
int i = 0
while(i < attribut_list.size())
{
((Attribut)attribut_list.elementAt(i)).bit_used = 0
i++
}
// no attributs are saved
store_cost_save_no = (int)compute_store_cost()
acc_cost_save_no = (int)compute_access_cost()
cost_save_no = (int)((1-z)*store_cost_save_no+
z*acc_cost_save_no)
store_cost_post_opt = store_cost_save_no
acc_cost_post_opt = acc_cost_save_no
cost_post_opt = cost_save_no
// compute the best subset of physical stored attributs
while(increment_attribut_list_bit_used())
{
store_cost_save_all = (int)compute_store_cost()
82
B.3 Java und JDBC Programme
acc_cost_save_all = (int)compute_access_cost()
cost_save_all = (int)((1-z)*compute_store_cost() +
z*compute_access_cost())
if(cost_save_all < cost_post_opt)
{
store_cost_post_opt = store_cost_save_all
acc_cost_post_opt = acc_cost_save_all
cost_post_opt = cost_save_all
int j = 0
while(j < attribut_list.size())
{
((Attribut)attribut_list.elementAt(j)).bit_best
=((Attribut)attribut_list.elementAt(j)).bit_used
j++
}
}
}
}catch(Exception x)
{
error +=
"\nERROR (method optimization_algorithm): "+
"optimization_algorithm \n"+
x.getMessage()
}
} // End of optimization_algorithm
private void delete_raw_image(Connection con)
{
String sql =
"SELECT DISTINCT mmdbsys.format(ext_image), quality "+
"FROM raw_image WHERE static = 0"
try
{
Statement stmt = con.createStatement()
ResultSet rs = stmt.executeQuery(sql)
while(rs.next())
{
String f = rs.getString(1)
int q = rs.getInt(2)
int i = 0
while(i < attribut_list.size())
{
Attribut a = (Attribut)attribut_list.elementAt(i)
if(((a.format).compareTo(f) == 0) &&
(a.quality == q) &&
(a.bit_best == 1))
break
i++
}
if(i == attribut_list.size())
{
String filename = "/home/db2inst4/DA/image/raw_image/"
String suffix = ""
if(q == 100)
suffix="s1."
else if(q == 75)
83
B.3 Java und JDBC Programme
suffix="s2."
else if(q == 50)
suffix="s3."
else suffix="s4."
sql = "DELETE FROM raw_image WHERE "+
"(mmdbsys.format(ext_image)= '"+f+"')"+
" AND (quality= "+q+") AND (static=0)"
try
{
Statement stmt2 = con.createStatement()
stmt2.executeUpdate(sql)
stmt2.close()
}catch(SQLException x)
{
error +=
"\nERROR (method delete_raw_image): "+
"DELETE on raw_image \n"+
x.getMessage()
}
// Delete also files containing the pictures
File f1 = new File(filename)
String ] list = f1.list()
String name = suffix + f
int k = 0
while(k < list.length)
{
if(list k].endsWith(name))
{
File f2 = new File(filename + list k])
f2.delete()
}
k++
}
k = 0
while(k < a_phys_list.size())
{
Attribut a = (Attribut)a_phys_list.elementAt(k)
if(((a.format).compareTo(f) == 0) &&
(a.quality == q))
a_phys_list.removeElementAt(k)
k++
}
} // end of if(i = attribut_list.size())
} // end of while(rs.next())
} catch (SQLException x)
{
error +=
"\nERROR (method delete_raw_image): "+
"SELECT on raw_image \n"+
x.getMessage()
}
} // end of method delete_raw_image
private void insert_raw_image(Connection con, Opti caller)
{
84
B.3 Java und JDBC Programme
int i = 0
while(i < attribut_list.size())
{
Attribut a = (Attribut)attribut_list.elementAt(i)
// target should be saved in raw_image
if(a.bit_best == 1)
{
int j = 0
// is target already in raw_image?
while(j < a_phys_list.size())
{
Attribut b = (Attribut)a_phys_list.elementAt(j)
if(a.equals(b))
break
j++
}
if(j >= a_phys_list.size())
{
String suffix
String option
if(a.quality==100)
{
suffix = "s1."
option = "-s 1"
}
else if(a.quality==75)
{
suffix = "s2."
option = "-s 0.75"
}
else if(a.quality==50)
{
suffix = "s3."
option = "-s 0.5"
}
else
{
suffix = "s4."
option = "-s 0.25"
}
suffix = suffix.concat(a.format)
// get the static_raw_images
String sql =
"SELECT name,mmdbsys.filename(ext_image) "+
"FROM raw_image WHERE static=1"
try
{
caller.output.append("\n"+a.format+a.quality+": ")
Statement stmt = con.createStatement()
ResultSet rs = stmt.executeQuery(sql)
// convert each image
while(rs.next())
{ caller.output.append(".")
String name = rs.getString(1)
String filename = rs.getString(2)
String filename_new =
85
B.3 Java und JDBC Programme
"/home/db2inst4/DA/image/raw_image/"
filename_new = filename_new.concat(name)
filename_new = filename_new.concat(suffix)
// DB2Image-UDFs need casting!
// writing converted picture into
// the .../raw_image directory
if(static_format.compareTo(a.format)==0)
{
String tmpfile = "/home/db2inst4/DA/tmp/tmp"
sql =
"SELECT mmdbsys.content(ext_image,CAST('"+tmpfile+
"' AS LONG VARCHAR),1, CAST('"+static_format+
"' AS VARCHAR(8)), CAST('"+option+
"' AS VARCHAR(100))) "+
"FROM raw_image "+
"WHERE static=1 AND quality = 100 AND "+
"name = '"+name+"'"
Statement stmt3 = con.createStatement()
ResultSet rs2 = stmt3.executeQuery(sql)
rs2.next()
rs2.close()
stmt3.close()
filename = tmpfile
sql =
"INSERT INTO raw_image VALUES("+
"mmdbsys.DB2Image(CURRENT SERVER," +
"CAST('"+filename+"' AS LONG VARCHAR),"+
"CAST('"+static_format+"' AS VARCHAR(8)),"+
"CAST('"+a.format+"' AS VARCHAR(8)),"+
"CAST('"+filename_new+"' AS LONG VARCHAR)"+
",' '),'"+name+"',"+a.quality+",0)"
}
else
{
sql =
"INSERT INTO raw_image VALUES("+
"mmdbsys.DB2Image(CURRENT SERVER," +
"CAST('"+filename+"' AS LONG VARCHAR),"+
"CAST('"+static_format+"' AS VARCHAR(8)),"+
"CAST('"+a.format+"' AS VARCHAR(8)),"+
"CAST('"+option+"' AS VARCHAR(100)),"+
"CAST('"+filename_new+"' AS LONG VARCHAR)"+
",' '),'"+name+"',"+a.quality+",0)"
}
try
{
Statement stmt2 = con.createStatement()
stmt2.executeUpdate(sql)
stmt2.close()
}catch(SQLException x)
{
error +=
"\nERROR (method insert_raw_image): "+
"INSERT on raw_image \n"+
x.getMessage()
}
} // end of while(rs.next())
86
B.3 Java und JDBC Programme
rs.close()
stmt.close()
}catch(SQLException x)
{
error +=
"\nERROR (method insert_raw_image): "+
"SELECT on raw_image \n"+
x.getMessage()
}
// add target to A_phys
Attribut b = new Attribut(a.format,a.quality,0,0)
a_phys_list.addElement(b)
} // end of if(j >= attribut_list.size())
} // end of if(a.bit_best == 1)
i++
} // end of while(i < attribut_list.size())
} // end of method insert_raw_image
// update the table conversion
private void update_conversion2(Connection con)
{
String sql = "UPDATE conversion SET is_allowed=0"
Statement stmt
try
{
// first set is_allowed=0 for all conversions
stmt = con.createStatement()
stmt.executeUpdate(sql)
stmt.close()
}catch(SQLException x)
{
error +=
"\nERROR (method update_conversion2): "+
"UPDATE on conversion (1) \n"+
x.getMessage()
}
int i = 0
while(i < a_phys_list.size())
{
Attribut a = (Attribut)a_phys_list.elementAt(i)
int j = 0
int min = 0
while(j < a_phys_list.size())
{
Attribut b = (Attribut)a_phys_list.elementAt(j)
if(((a.format).compareTo(b.format)==0)
&& (b.quality>min)
&& (b.quality < a.quality))
min = b.quality
j++
}
sql =
"UPDATE conversion SET is_allowed=1 WHERE "+
"(source_format = '"+a.format+
"') AND (source_quality = "+a.quality+")"+
87
B.3 Java und JDBC Programme
" AND (target_format = '"+a.format+
"') AND (target_quality <= "+a.quality+
") AND (target_quality > "+min+
") AND NOT ((source_format = 'eps' OR "+
"source_format = 'ep2' OR source_format = 'ps' OR "+
"source_format = 'psc' OR source_format = 'ps2') AND "+
"source_quality != target_quality)"
try
{
stmt = con.createStatement()
stmt.executeUpdate(sql)
stmt.close()
}catch(SQLException x)
{
error +=
"\nERROR (method update_conversion2): "+
"UPDATE on conversion (2) \n"+
x.getMessage()
}
i++
} // end of while(i < attribut_list.size())
sql =
"SELECT target_format,target_quality FROM conversion "+
"GROUP BY target_format,target_quality "+
"HAVING max(is_allowed)=0"
try
{
stmt = con.createStatement()
ResultSet rs = stmt.executeQuery(sql)
while(rs.next())
{
sql =
"UPDATE conversion SET is_allowed=1 WHERE "+
"(source_format='"+static_format+
"') AND (source_quality="+static_quality+
") AND (target_format='"+rs.getString(1)+
"') AND (target_quality="+rs.getInt(2)+")"
try
{
Statement stmt2 = con.createStatement()
stmt2.executeUpdate(sql)
stmt2.close()
}catch(SQLException x)
{
error +=
"\nERROR (method update_conversion2): "+
"UPDATE on conversion (3) \n"+
x.getMessage()
}
} // end of while(rs.next())
rs.close()
stmt.close()
}catch(SQLException x)
{
error +=
"\nERROR (method update_conversion2): "+
88
B.3 Java und JDBC Programme
"SELECT on conversion \n"+
x.getMessage()
}
} // end of method update_conversion2
private void save_log(Connection con)
{
String hd = "", hc = ""
int i = 0
while(i < hd_size.length)
{
hd += hd_size i] + " "
hc += hd_cost i] + " "
i++
}
String a_phys = ""
i = 0
while(i < a_phys_list.size())
{
Attribut a = (Attribut)a_phys_list.elementAt(i)
a_phys += a.format + a.quality + " "
i++
}
String sql =
"INSERT INTO opti_log VALUES("+
"CURRENT TIMESTAMP,'"+
static_format+"',"+
z+","+
c_s+","+
c_a+","+
c_c+","+
p+","+
q+","+
num+",'"+
hd+"','"+
hc+"',"+
comp_time+","+
total_time+","+
acc_cost_pre_opt+","+
store_cost_pre_opt+","+
acc_cost_save_all+","+
store_cost_save_all+","+
acc_cost_save_no+","+
store_cost_save_no+","+
acc_cost_post_opt+","+
store_cost_post_opt+",'"+
a_phys+"')"
try
{
Statement stmt = con.createStatement()
stmt.executeUpdate(sql)
stmt.close()
} catch (SQLException x)
{
error +=
"\nERROR (method save_log): "+
89
B.3 Java und JDBC Programme
"INSERT on opti_log \n"+
x.getMessage()
}
} // end of method save_log
} // end of class Optimization
90
Literaturverzeichnis
BB99]
Jon Bosak und Tim Bray. Mehr Tempo auf der Datenautobahn.
Neue Web-Sprache XML. Spektrum der Wissenschaft, Seiten 74 {
79, 7/99.
Cha96]
Don Chamberlin. Using the new DB2. Morgan Kaufmann Publishers, 1996.
Com]
Command Reference.
http://www.software.ibm.com/cgibin/db2www/library/document.d2w/report?fn=db2n003.htm.
CW97]
Mary Campione und Kathy Walrath. Das Java Tutorial. AddisonWesley, 1997.
Ext]
DB2
Universal
Database
Image,
Audio,
and
Video
Extenders
Administration
and
Programming.
http://www.software.ibm.com/cgibin/db2www/library/document.d2w/report?fn=dmba5m03.htm.
KEUB+ 98] Werner Kieling, Katharina Erber-Urch, Wolf-Tilo Balke, Thomas
Birke und Matthias Wagner. The HERON Project | Multimedia Database Support for History and Human Sciences. In: Rudolf Kruse (Herausgeber): 28. Annual Conference of the German
Computer Society (GI): INFORMATIK98, LNCS, Seiten 309{318,
Magdeburg, Germany, September 1998. Springer Verlag Heidelberg.
KK98]
Werner Kieling und Gerhard Kostler. Multimedia-Kurs Datenbanksysteme. Springer-Verlag, 1998.
KKK97] Gerhard Kostler, Wolfgang Kowarschick und Werner Kieling.
Client-Server Optimization for Multimedia Document Exchange.
In: Proceedings of the Fifth International Conference on Database Systems for Advanced Applications, Seiten 135{144, Melbourne,
Australia, April 1997.
Mo98]
Bernhard Moller. Skript zur Vorlesung Informatik II. Institut fur
Informatik, Universitat Augsburg, 1998.
MS93]
Jim Melton und Alan R. Simon. Understanding the new SQL: A
complete guide. Morgan Kaufmann Publishers, 1993.
Literaturverzeichnis
Rie97]
Sie56]
92
Peter Rieger. Implementierung einer Client-Server-Optimierung
fur den Austausch von Multimedia-Dokumenten. Diplomarbeit,
Universitat Augsburg, 1997.
Johann Siebmacher. Siebmachers groes Wappenbuch. Bauer &
Raspe, 1856.
Herunterladen