Hauptseminar Datenbanksysteme: Datenbanken

Werbung
Hauptseminar Datenbanksysteme: Datenbanken und XML
Thema: Efficiently Publishing Relational Data as XML Documents
Seminar-Vortrag am 18.12.2001
von Dennis Säring
Inhalt
1. Einführung und Motivation
2. Wiederholung ( XML )
3. Ein Beispiel kurz erläutert mit Quellcode belegt
4. Ausführliche Vorstellung der Alternativen
5. Beurteilung der Effizienz aller Alternativen
6. Abschließender Kommentar und Ansätze für die Zukunft
7. Referenzen
1. Einführung und Motivation
Das Ablegen großer Datenmengen in relationale Datenbanken und die zunehmende
Verwendung von XML zur Veröffentlichung dieser Daten im WWW fordern Methoden die
Tabellen effizient zu strukturieren und in Tag-Form zu bringen.
Im folgenden Dokument erläutere ich verschiedene Ansätze und deren Vor- und Nachteile
bezüglich der Effizenz.
Im Wesentlichen sind dabei zwei Hauptvoraussetzungen zu erfüllen:
1. Eine Sprache, die die Umsetzung ( Strukturierung und Tagging ) von rel. Daten in XMLDokumente spezifiziert.
Hierbei wird das bestehende SQL-System durch skalare Funktionen erweitert, um das
aufwendige Entwickeln einer komplett neuen Sprache zu umgehen. Es ist außerdem
möglich Standart-APIs wie ODBC zu verwenden um XML-Dokumente zu erhalten. Dies
erlaubt bei bestehenden Tools und Anwendungen eine einfache Integration von
relationalen Systemen und XML.
Eine Kombination aus SQL und XML Anfragesprachen ist ebenso möglich.
2. Eine Implementation, die diese Umsetzung möglichst effizient vollzieht.
Die relationalen Tabellen sind flach organisiert. Im Gegensatz dazu sind XMLDokumente hierachisch-, graphen- und tagged-strukturiert. Implementationen
unterscheiden sich in Ort und Zeit ihrer Ausführung
2. Wiederholung ( XML )
XML ist ein hierachisches Format zur Veröffentlichung von Daten im WWW, bestehend aus
verschachtelten Elementen. Jedem Element wird eine Markierung ( Tag ) zugeordnet.
Desweiteren können Elemente Attribute und Subelemente enthalten. In XML können
Elemente geordnet werden.
<customer id=“C1“>
<name> John Doe </name>
<accounts>
<account id=”A1”> 1894654 </account>
<account id=”A2”> 3849342 </account>
</accounts>
<porders>
<porder id=”P01” acct=”A2”> // first purchase order
<date> 1 Jan 2000 </date>
<items>
<item id=”I1”> shoes </item>
<item id=”I2”> bungee ropes </items>
</items>
<payments>
<payment id=”P1” due Jan 15 </payment>
<payment id=”P2” due Jan 20 </payment>
<payment id=”P3” due Feb 15 </payment>
</payments>
</porders>
<porder id=”P02” acct=”A1”> // second purchase order
…
</porder>
</customer>
Customer ( id
integer,
name varchar(20) )
Account ( id
varchar(20),
custId integer,
acctnum integer )
PurchOrder ( id
custId
acctId
date
Item ( id
integer,
poId integer,
desc varchar(10) )
integer,
integer,
varchar(20),
varchar(10) )
Payment ( id
integer,
poId integer,
desc varchar(10) )
Abb. 1
Abb. 2
3. Auf SQL basierende Sprache zur Veröffentlichung rel.Daten in XML
Wie bereits erwähnt, ist die Ausarbeitung einer Sprache zur Spezifikation der XMLKonvertierung von relationalen Daten wesentlich. Man hat nun die Möglichkeit eine neue
Sprache speziell für dieses Problem zu erstellen oder wie es in dieser Untersuchung
favourisiert wird, die bestehenden Ressourcen zu nutzen und zu erweitern. Dazu werden
geschachtelte SQL-Strukturen zum nested-structuring und SQL-Funktionen zur Konstruktion
von XML Elementen verwendet.
Betrachten wir nun das relationale Schema „Customer“ ( Abb.2 ) Zu beachten sind die
verschiedenen Tables ( Customer, Account, PurchaseOrder, Item, Payment ), deren IDs, deren
zugeordneten Attribute und ihre Fremdschlüsselrelationen.
Select cust.name CUST(cust.id, cust.name,
(Select XMLAGG(ACCT(acct.id,acct.acctnum))
From Account acct
Where acct.custId = cust.id),
(Select
XMLAGG(PORDER(porder.id,porder.acct,porder.date,
(Select XMLAGG(ITEM(item.id,item.desc))
From Item item
Where item.poId = porder.id),
(Select
XMLAGG(PAYMENT(pay.id,pay.desc))
From Payment pay
Where pay.poId = porder.id)))
group order by porder.date
From PurchOrder porder
Where porder.custId = cust.id))
From Customer cust
Abb. 3
create function CUST (custId :
integer,
custName : varchar(20),
acctList : XML,
porderList : XML )
returns xml language xml
return
<customer id={custId }>
<name>
{custName} </name>
<accounts> {acctList} </accounts>
<porders > {porderList} </porders >
</customer>
Abb.4
Eine Möglichkeit der Konvertierung wird in Abb. 3 dargestellt. Innerhalb einer SQL Anfrage
werden sowohl SQL- als auch XML-Daten erstellt. Das Ergebnistupel setzt sich zusammen
aus dem CustomerName zusammen mit seiner XML-Representation.
Die gesamte Query besteht aus Sub-Queries, die alle weiteren Tables und deren XMLDarstellung generieren. Die XML-Elemente werden mit Hilfe des XML-Konstruktors erstellt.
Einen Beispiel-Konstruktor für den Customer sieht man in Abb. 4. Ihm wird der
CustomerName, AccountInf. ( in XML-Form ) und PurchaseOrderInf. ( in XML-Form )
übergeben. Das Ergebnis ist das Customer-XML-Element.
Der Konstruktor ist eine skalare Funktion, die ein XML-Fragment mit den übergebenen
Parametern zurück gibt. Alle anderen Tables ( Account, PurchaseOrder, Payment, Item )
werden ähnlich in XML konvertiert. XMLAGG fügt die Elemente zu einem vollständigen
XML-Dokument zusammen. Um die XML-Fragmente in der richtigen Reihenfolge geordnet
zusammen zu setzen, muß XMLAGG bereits geordnete Werte ( Inputs ) erhalten.
4. Alternativen von Implementationen
Relationale Datenbanken unterscheiden sich von XML-Dokumenten durch die Struktur und
die Tags. Somit ergeben sich zwei wesentliche Aufgaben:
§ Strukturierung der Daten; Konvertierung in ein geschachteltes hierachisches System
§ Eintragung von Tags; Einfügen von Textuellen Fragmenten
Um die verschiedenen Alternativen möglichst klar voneinander abzugrenzen, unterteilt man
die Ansätze nach den zeitlichen Gesichtspunkten:
§
§
frühes Markieren / spätes Markieren
( early tagging / late tagging )
frühes Strukturieren / spätes Strukturieren
( early structuring / late structuring )
early tagging
late tagging
outside
early structuring
inside
outside
inside
outside
( frühes Markieren macht ohne vorheriges
Strukturieren keinen Sinn )
late structuring
inside
Abb. 5
Diese 3 Alternativen ( Abb. 5 ) werden noch zusätzlich unterschieden, ob die Arbeit innerhalb
der relationalen Maschine erledigt werden kann.
§ inside the engine ( completely inside )
§ outside the engine ( not necessarily all outside )
4.1. early tagging & early structuring
4.1.1. the stored procedure approach
Der einfachste Weg relationale Daten zu strukturieren, ist die Verwendung einer
explizit geschachtelten Anfrage, welche die Daten in XML-Form bringt.
Man beginnt bei der Wurzel und arbeitet sich dann iterativ nach unten durch. Im
Beispiel aus Abb.1 würde man zuerst den Customer mit all seinen Attributen in XMLForm bringen, dann mit Hilfe der CustomerID die dazugehörige Account konvertieren,
dann die PurchaseOrder. Anschließend ( ein level tiefer ), verarbeitet eine Query Item
und Payment. Der Prozess für einen Customer ist nun abgeschlossen, für jeden
weiteren Customer muß die Prozedur erneut durchgeführt werden. Ordnen kann man
die Struktur innerhalb der SQL-Anfrage mit Hilfe der bekannten order by Anweisung.
Hier wird eine externe Schleife über SQL-Anweisungen zur Strukturierung der Daten
genutzt. Das Strukturieren und Markieren geschieht hier frühzeitig, daher
charakterisiert man diesen Ansatz als early tagging & early structuring ouside the
engine. Dieser Ansatz beinhaltet zwei Probleme, zum einen sind eine große Anzahl an
SQL-Queries nötig ( äußerst ineffizient ), zum anderen fordert diese Methode eine
Sortierung beim union und Schleifenmethoden zur Schachtelung. Hier wären andere
Methoden eventuell sinnvoller, bzw effektiver.
4.1.2. the correlated CLOB approach
Um die große Anzahl an Queries zu umgehen verlagert man alles in eine große Query
mit Sub-Queries. Das tagging und structuring ist komplett innerhalb der Maschine zu
lösen, durch die Verwendung von XML-Konstruktoren und der XMLAGG-Funktion.
Die erstellte Query wird dann als nested-Query ausgeführt, sie folgt dabei im
wesentlichen der bereits in Abb. 3 gezeigten Sprache. Die konstruierten XMLFragmente können dabei beliebig groß werden, so dass diese als große Objekte
[ CLOBs ], ( Character Large Objects ) betrachtet werden. Die festen Zuordnungen
( Correlation ) der Tables fordern wieder Schleifen zur Schachtelung, die wiederum
Einbußen bei der Effizienz zur Folge haben. Objekte werden unabhängig von ihren
Tupeln abgelegt, so kann das Speichern in parallen Netzen ineffizient werden. Bei
einer Sortierung müssen Objekte in den Zwischenspeicher kopiert werden (overhead).
Der Aufruf eines XML-Konstruktors ist somit sehr teuer.
( custXML )
CUST()
Data flow
Correlation
( custId,custName )
Customer
( acctXML )
Groupby:
XMLAGG(ACCT())
( acctId, acctNum )
Join
custId = acct.custId
( poXML )
custID
Groupby:
XMLAGG(PORDER())
( poId, poAcct, poDate )
Join
custId = po.custId
( itemXML )
( payXML )
Groupby:
XMLAGG(ITEM())
Groupby:
XMLAGG(PAY ())
custID
( custId, acctId, acctNum )
Account
( custId, poId, poAcct, poDate )
poID
PurchOrder
poID
( itemId, itemInfo )
( payId, payInfo )
Join
poId = item.poId
Join
poId = pay.poId
(poId, itemId, itemInfo )
(poId, payId, payInfo )
Item
Payment
Abb. 6
4.1.3. the decorrelated CLOB approach
Um die Verwendung von Schleifen zu umgehen, kann eine Query ohne feste
Zuordnung ( de-correlated ) erstellt werden, dadurch wird ein hohes Maß an
Flexibilität gewonnen. ( Abb. 7 )
Die Verbindung von der Wurzel zu den jeweiligen Blättern wird durch einen
join hergestellt. Diese outer-joins werden verwendet, damit Informationen über den
Stamm erhalten bleiben. Die XML-Darstellung der Blätter wird erstellt und unter
Verwendung von XMLAGG eine Gruppierung nach ID des Parent vorgenommen.
Durch die Id kann der Pfad zurück verfolgt werden.
Die Struktur wird erstellt durch das Zusammenführen dieser ID-Felder und der
anschließenden Verwendung des XML-Konstruktors, dieses wird bis zum root-level
ausgeführt.
Dieser Ansatz ist zwar flexibler, beinhaltet aber die gleichen Probleme wie der
correlated-CLOB Ansatz, da auch hier durch das frühe Strukturieren und Markieren,
das Zwischenspeichern von CLOBs nötig ist.
( custXML )
Join: CUST()
custId = custId
( custId, porderXML )
Groupby: custId
XMLAGG(PORDER())
( custId, poId, poAcct, poDate, itemXML, payXML )
Join
custId = custId and poId = poId
( custId,poId,poAcct,poDate,itemXML )
Groupby: custId, poId
XMLAGG(ITEM())
( custId, poId, payXML )
Groupby: custId, poId
XMLAGG(PAY())
( custId, custName, acctXML )
Groupby: custId
XMLAGG(ACCT())
( custId,poId,poAcct,poDate,itemId,itemInfo )
( custId,poId,payId,payInfo )
Right Outer Join
item.poId = po.id
Left Outer Join
pay.poId = po.id
(custId, custName, acctId, acctNum)
Right Outer Join
acct.custId = custId
( itemId, itemInfo )
Item
( custId, acctId, acctNum )
( custId,custName )
Account
Customer
Left Outer Join
cust.id = po.custId
Payment
( custId, potId, poAcct, poDate )
PurchOrder
Abb. 7
4.2. late tagging & late structuring
Das Erstellen von XML-Dokumenten, wobei Strukturieren und Markieren am Ende
stattfindet, unterteilt sich in zwei wesentliche Schritte:
1. Das Erstellen der relationalen Daten ( content creation )
2. Das Strukturieren und Markieren zur Erstellung des XML-Dokuments
( structuring / tagging )
Die folgenden Ansätze werden komplett innerhalb der Maschine verwirklicht um
auszunutzen, daß Funktionalitäten wie join bereits gegeben sind.
4.1.4. content creation: redundant relation approach
Erstelle die Daten durch einen join über alle Tables, wobei die Beziehungen beachtet
werden müssen ( Abb. 8 ).
Es ergeben sich dadurch zwei Probleme, zum einen verwendet man redundante
Prozesse und zum anderen erhält man durch den join redundante Inhalte. So werden
beispielsweise die Informationen des Customer_Accounts unnötigerweise
PurchaseOrder * Items per PO * Payments p. PO wiederholt. Dadurch wird der
enstehende Table unnötig groß. Das Umwandeln in eine hierachische Struktur wird
aufwendig.
Select cust.id, cust.name, acct.id, acct.num, po.id, po.acctId, po.date, item.id, item.info, pay.id, pay.info
From Customer cust
left join Account acct on cust.id = acct.custId
left join PurchOrder po on cust.id = po.custId
left join Item item on po.id = item.poId
left join Payment pay on po.id = pay.poId
Abb. 8
4.2.2. content creation: ( unsorted ) outer union approach
Mit diesem Ansatz wird versucht die multiplikative durch eine additive Vergrößerung
zu ersetzen, um so zu viele redundante Daten zu vermeiden. Dazu betrachten wir die
einzelnen Blätter eines Stammes separat, so wird auf dem Pfad nur die Repräsentation
dieses Astes gespeichert und keine Informationen seiner Nachbarn. ( Abb. 9 )
Im Beispiel werden 3 Pfade ( path outer union ) erstellt, ( Customer-Account,
CustomerPurchaseOrder-Item und CustomerPurchaseOrder-Payment ) so wird viel
redundante Vervielfälltigung vermieden. Zuletzt werden alle Tupel zu einer Relation
zusammengefasst ( outer union ), dabei müssen folgende Dinge beachtet werden:
§ Die Anzahl der Spalten kann sich von Blatt zu Blatt unterscheiden, durch das
Einfügen von null-Spalten stellt man die Gleichheit wieder her
§ Der ursprünglichen Pfad geht verloren, dieses umgeht man durch das Hinzufügen
einer Type-Spalte die quasi den dazugehörigen Pfad identifiziert
( type, custId, custName, acctId, acctNum, poId,
poAcct, poDate, itemId, itemInfo, payId, payInfo )
Outer Union
( custId, poId, poAcct, poDate, itemId, itemInfo )
( custId, poId, payId, payInfo )
Rigth Outer Join
poId = poId
Left Outer Join
poId = poId
( custId, custName, acctId, acctNum )
Item
( custId, poId, poAcct, poDate )
Rigth Outer Join
custId = custId
( acctId, acctNum )
Account
Payment
Left Outer Join
poId = poId
( poId, poAcct, poDate )
( custId, custName )
PurchaseOrder
Customer
Path Outer Union - Abb.9
Redundante Daten erhält man hier durch die Wiederholung von root-Daten, man
könnte diese auch direkt in das outer union schreiben ( node outer union ( Abb. 10 )),
würde so allerdings eine größere Anzahl an Tupel bekommen, was wiederum nicht
unbedingt effizient wäre.
Bei diesem Ansatzt wächst die Anzahl der Spalten, mit der Tiefe und Weite des XMLDokuments, obwohl nur wenige Tupel Daten enthalten ( viel null-wertigen Spalten ),
kann sich durch das Nicht-komprimieren von null-Werten die Effizienz verringern.
4.2.3. structuring / tagging: hash-based tagger
Nachdem die relationalen Daten nun auf XML-Struktur gebracht wurden, müssen
diese noch getagged werden. Eine Möglichkeit innerhalb der Maschine zu taggen ist
die Verwendung von den bereits vorgestellten XML-Konstruktoren und dem
XMLAGG. ( wieder das Problem aus dem CLOB Ansatz )
Ob inner- oder außerhalb der Maschine, im wesentlichen sind 2 Aufgaben zu lösen.
§ Zusammenfassen aller Geschwister gleicher Eltern und löschen von doppelten
Elementen
§ Jedes Tupel analysieren und entsprechend markieren um das XML-Dokument
fertig zu stellen.
Die erste Aufgabe kann man mit Hilfe eines Hash-basierten Ansatzes lösen.
Ein Tupel, welches Informationen bezüglich eines XML-Elements enthält, wird in
einem Hashtable eingefügt unter Beachtung seines Element-Types und der ID seines
Parent, so kann festgestellt werden ob sein Parent bereits im Table vorhanden ist.
Ist dies der Fall, wird ein neues XML-Element erstellt und als child eingefügt, falls
nicht, wird ein hash ausgeführt auf Typ und IDs aller Vorfahren ausgenommen Parent.
Auf dieser Art wird das Dokument durchlaufen bis zum root Element.
Nachdem alle Tupel „gehashed“ wurden, kann die XML-Datei geschrieben werden.
Falls eine bestimmte Ordnung der Elemente gefordert ist, wird dies entweder bei
Erstellung eines Childs oder zuvor in einem Sortierverfahren geschehen.
Dieser Ansatz ist effizient, wenn genügend Speicher für die Tabellen zur Verfügung
steht, ist dies nicht der Fall, wird der Ansatzt schnell ineffizient. Lösung hierfür wäre
eine Partitionierung der Daten ( verteiltes Hashing ).
( type, custId, custName, acctId, acctNum, poId,
poAcct, poDate, itemId, itemInfo, payId, payInfo )
Outer Union
( custId, poId, itemId, itemInfo )
( custId, poId, payId, payInfo )
Join
poId = poId
Join
poId = poId
( custId, custName, acctId, acctNum )
Join
custId = custId
( poId,itemId,itemInfo )
Item
( custId, acctId, acctNum )
Account
( custId, poId, poAcct, poDate )
( poId,payId,payInfo )
Join
custId = custId
Payment
( custId, poId, poAcct, poDate )
( custId, custName )
PurchaseOrder
Customer
Node Outer Union - Abb.10
4.3. late tagging & early structuring
Das Erstellen von strukturiertem Inhalt und anschießendem tagging mittels eines
platzkonstanten Taggers wird hier verwendet, um das Problem der Speicherverwaltung
aus 4.2.2 zu umgehen.
4.3.1. structured content creation: sorted outer union approach
Die relationalen Daten müssen so sortiert werden, wie sie dann auch ins XMLDokument geschrieben werden sollen. Dabei muß folgendes beachtet werden:
1. Die Information eines Parent kommt vor der Information vom Child
2. Auf Informationen eines Knotens folgen die Informationen seiner Nachfolger,
Informationen von Nicht-Nachfolgern werden nicht mit hinein gemischt
Im folgenden wird anhand des path-outer-union Ansatzes gezeigt, dass es ausreichend
ist eine eine Sortierung auf dem unstruktiertenEgebnis von 4.2.2. auszuführen um die
oben beschriebenen Forderungen zu erfüllen.
Um Bedingung 1 und 2 zu erfüllen, muß das Ergebnis des outer union Ansatzes nach
IDs sortiert werden. ( IDs der parents sind höher als IDs der childs ) Im Outer Union
Null Spalten hinzugefügt, wenn ein Eintrag von A nicht keinen „Partner“ in B hat. Die
dadurch entstehenden Tupel mit null-wertigen Einträgen müssen in der
Sortierreihenfolge vor den anderen Tupeln stehen, somit ist gesichert, dass parentTupel vor den child-Tupeln stehen ( Bedingung 1 ). Ebenso werden hiermit die Childs
des jeweiligen parent in einer Gruppe hinter dem Parent sortiert, was die Bedingung 2
erfüllt.
( type, custId, custName, acctId, acctNum, poId, poAcct, poDate, itemId, itemInfo, payId, payInfo )
Order by: custId, poDate, poId, acctId, payId, itemId
( type, custId, custName, acctId, acctNum, poId,
poAcct, poDate, itemId, itemInfo, payId, payInfo )
Outer Union
( custId, poId, poAcct, poDate, itemId, itemInfo )
( custId, poId, payId, payInfo )
Rigth Outer Join
poId = poId
Left Outer Join
poId = poId
( custId, custName, acctId, acctNum )
Item
( custId, poId, poAcct, poDate )
Rigth Outer Join
custId = custId
( acctId, acctNum )
Account
Payment
Left Outer Join
poId = poId
( poId, poAcct, poDate )
( custId, custName )
PurchaseOrder
Customer
sorted Path Outer Union - Abb.9a
Dieser Ansatz hat den Vorteil große Datenvolumen speicherfreundlich zu sortieren,
und mit geringem Kostenaufwandt Benutzeranfragen zu erfüllen. Da es aber nicht
wichtig ist alle „Geschwister“ zu sortieren ( es ist lediglich nötig die Reihenfolge von
parents und childs einzuhalten), wird zu viel Arbeit in die Gesamtsortierung gesteckt.
4.3.2. tagging sorted data: constant space tagger
Die strukturierten Daten werden in ihrer sortierten Reihenfolge eingelesen und
markiert. Der Tagger benötigt Speicher, um sich die IDs des parent zu merken, um so
entscheiden zu können, ob ein Endtag gesetzt werden muß oder nicht. Die Größe des
Speichers ist konstant in der Anzahl der Level und unabhängig von der Größe des
XML-Dokumentes.
5.
Beurteilung bzgl. Effizienz der vorgestellten Alternativen
Vor- und Nachteile der Methoden wurden bereits erwähnt, im folgenden Abschnitt wird
untersucht welche Methode wann am sinnvollsten angewendet wird.
Es werden insgesamt vier Parameter definiert, mit denen man die einzelnen Tests variieren
kann und Schlüsse aus den Ergebnissen ziehen kann.
5.1. Modellerstellung
Um die Schachtelung der Daten zu charakterisieren, definiert man zwei Parameter, der
Erste gibt die maximale Anzahl von sub-querys eines parents an, ( query fan out ) der
Zweite repräsentiert die Tiefe der Schachtelung ( query depth ).
In diesem Versuch werden nur ausgeglichene Strukturen verwendet.
§
jedes Element, welches kein Blatt ist, hat die gleiche Anzahl an direkt
verschachtelten Sub-Queries
§ alle Blätter haben die gleiche Tiefe, bzw. sind auf dem selben Level
Diese beiden Parameter ( fan out & depth ) spezifizieren lediglich die Struktur.
Die Effekte der Variierung dieser Parameter ist Ziel der Untersuchung, nicht die
Komplexität der SQL-Query zur Erstellung eines XML Elementes.
Im folgenden wird ein Schema verwendet, ähnlich dem aus Abb.2 + Abb.3, jede
Relation wird durch einen Table dargestellt. Ein Table enthält einen ID Eintrag (
Primary key ) und eine ParentJoinID Eintrag ( Foreign key ), um parents und childs zu
verknüpfen, wird jeweils ein join über ID und PJID ausgeführt. Zusätzlich zu den beiden
Feldern werden zwei Datenfelder unterschiedlichen Typs ( IntVal : Integer ) & (
CharVal : String[20] ) hinzugefügt.
Die beiden anderen Parameter reichen aus um die Datenbank zu beschreiben, zum einen
number of roots, der die Anzahl der Tupel im root level wiedergibt. Der zweite
Parameter ist number of leaf tuples, der entspricht der Anzahl aller Blatt-level Tupel
geteilt durch die Anzahl aller Blatt-level Tables. ( Tupel pro Table ). Zusammengefaßt
erhält man den instance fan out, der die Anzahl der Child-Tupel jedes Typen, der einen
Parent-Tupel besitzt, spezifiziert. ( Voraussetzung dafür ist, daß jedes Parent Tupel die
gleiche Anzahl an Child Tupel besitzt )
Der Parameter number of leaf tuples ist interessant, da dieser Wert in Beziehung zur
Größe des entstehenden XML-Dokuments steht, und es somit möglich ist bei konstanter
Anzahl an leaf tupels die unterschiedlichen Strukturierungs Ansätze zu analysieren.
Das gewonnene XML-Dokument sieht folgendermaßen aus:
§
die Werte der Int und Char Spalte wurden mit einen String der Länge 3 markiert
§
die XML-Fragmente der Child Tupel sind verschachtelt unter den der parents
§
das Ergebnis ist immer ein einzelnes gesamtes XML-Dokument
Zu beachten ist, dass lediglich number of roots und number of leaf tuples variieren und
die Tables gleich bleiben.
5.2. Aufbau des Experiments
Implementation der Alternativen auf DB2 System, wobei die XML-Konstruktoren und
XMLAGG als built-in Funktionen umgesetzt wurden. Der stored procedure Ansatz läuft
im gleichen Addressraum wie die relationale Maschine ( unfenced ), um die
Performence zu maximieren. Alle outside the engine Ansätze werden lokal als
eingebundene SQL-Programme auf der gleichen Maschine wie der DB Server
implementiert, um so Kommunikationsaufwand im Netz zu vermeiden. Die
Zeitmessung erfolgt über ein SQL-Programm, die Ausgabe wird in eine NT-Datei
geschrieben. Ein Pentium 366 MHz, 256 MB Arbeitsspeicher und das Windos NT 4.0
Betriebssystem bilden die Hardware.
Die verwendeten Parameter wurden wie in Abb. 11 dargestellt variiert. Alle Prozesse
konnten innerhalb des Arbeitsspeichers abgewickelt werden, somit gibt es keinen
Verlust von Effizienz durch Auslagerung. Da sich node-outer-union und path-outerunion nur sehr gering unterschieden, wurde standartmäßig mit path-outer-union getestet,
deren Unterschiede werden dann im Anschluß separat diskutiert.
Parameter
Query Fan Out
Query Depth
# Roots
# Leaf Tuples
Range of Values
2, 3, 4
2, 3, 4
1, 50, 500, 5000, 40000
160000, 320000, 480000
Default
2
2
5000
320000
Abb. 11
5.3. Inside the engine vs. ouside the engine
Zunächst wird der query fan out variiert und die restlichen Parameter konstant gehalten.
In Abb. 12 a & b werden inside und ouside Ansätze verglichen, wobei redundant
relation nicht mit aufgetragen wurde da dessen schlechte Performence bei hohem fan
out zu gravierend war.
( Seine reine Ausführungszeit bei einem fan out von 4 betrug rund 155 Sek )
Abb. 12a
Abb. 12b
Abb. 12 b zeigt deutlich den overhead beim stored procedure Ansatz, der correlated
CLOB Ansatz ( inside the engine ) benötigt nur ein Drittel gegenüber ( outside the
engine ). Die inside Methoden sind durchweg effizienter.
In Abb. 13 sind die einzelnen Zeitaufwände aufgezeigt,
§ Zeit zum Umformen der relationalen Daten ( execution )
§ Zeit um den relationalen Inhalt für outside Funktionen verfügbar zu machen
( bind out )
§ Zeit den Inhalt zu taggen und möglicherweise das Ergebnis zu strukturieren
( tagging )
§ Zeit die gewonnene Ergebnis in eine Datei zu schreiben ( XML file )
Zu beachten ist folgendes: inside the engine
Ansätze enthalten kein bind out und CLOB
Ansätze besitzen tagging als festen Bestandteil
der execution. Es ist deutlich zu beobachten,
daß den größte Zeitanteil der outside Ansätze
das bind out einnimmt, auch durch anpassen
der Kommunikationsparameter ( z.B. Buffervergrößerung ) erhält man kein besseres
Ergebnis. Somit disqualifizieren sich die
outside the engine Ansätze für weitere
Untersuchungen, dennoch haben diese Ansätze
den Vorteil, daß sie bei Datenbanken eingesetzt werden können,
die keine zusätzlichen XML-Funktionen unterstützen.
Abb. 13
5.4. Effekt des query fan out
Eine Erhöhung des query fan out Wertes erzeugt einen größeren Zeitaufwand bei der
Erstellung des XML-Dokumentes, begründet ist dies durch die größere Anzahl an joins
die durchgeführt werden müßen. Betrachtet man die Ansätze einzelnd, fällt auf, daß der
correlated CLOB die schlechtesten Werte hervorbringt. Grund dafür ist die Verwendung
der verschachtelten loop joins. Desweiteren ist zu beobachten, daß der unsortet outer
union plan effizienter als der sortet outer union plan ist. Die Verwendung von
komplexen Hashtabellen scheint effizienter ( zumindest bei genügend Speicher ) zu sein
als eine Sortierung mit anschließendem platzkonstanten Tagger.
Ein überaschendes Ergebnis erhält man für den decorrelated CLOB Ansatz, der bei
kleinem fan out die besten Werte liefert. Grund hierfür ist der DB2 Optimierer, welcher
kleinere Objekte im Hauptspeicher behält, ebenso bleibt der overhead bei geringer query
depth klein.
In Abb. 12 b sind die Werte der outer engine Ansätze dargestellt, hier zeigt sich die
stored procedure Methode als ineffektiv
( zu viele queries müssen erstellt werden; Verwendung einer fixen join Strategie ).
Im Gegensatz zur inside the engine Umsetzung, sind die Ergebnisse des sorted und
unsorted outer union Ansatzes outside sehr ähnlich, da hier der Tagger ein streaming
Operator ist, d.h. sobald ein Tupel erkannt wird, wird dieses in die Datei geschrieben,
wohingegen der hash-basierte zunächt alle Prozesse abwarten muß und erst dann die
XML Datei schreiben kann.
5.5. Effekt der query depth
In Abb. 14 sieht man die Ergebnisse ( inside the engine ) bei Variierung des query depth
Parameters. Die de-correlated CLOB Methode steigt mit der Tiefe gegenüber den
anderen Kandidaten drastisch an. Begründen kann man dies mit den Fehlern die der
relationale query Optimierer begeht, wenn die Queries zu komplex werden. Der
Optimierer entscheidet sich beispielsweise zu einer Sortierung der Daten nach
Ausführung von XMLAGG, hierbei müssen einige CLOBs in temporären Speicher
kopiert und wieder verwendet werden, was die Effektivität stark verringert. Die
traditionellen Optimierer können mit der Aggregatsfunktion nicht viel anfangen und
somit die Größe des CLOB Ergebnisses nicht gut kalkulieren.
5.6. Effekt der number of roots
Allgemein kann man sagen, daß das Ändern dieses Parameters keine wesentlichen
Auswirkungen auf die Laufzeit der verschiedenen Methoden hat, lediglich die Methode
des correlated CLOBs optimiert sich bei wenig root Elementen und verschlechtert sich
relativ zu den anderen stark bei größeren Werten für number of roots.
( Bei nur einem root-Element müssen nur 2 sub-queries erstellt werden, sehr effektiv )
Abb. 14
Abb. 15
5.7. Effekt der number of leaf tuples, memory size
Es sind keine gravierenden Einbußen der Effizienz zu erkennen, wenn man die Anzahl
der leaf – Tupel erhöht und genügend Speicherplatz zur Verfügung steht.
Bei zu wenig Hauptspeicher zeigt sich, daß die unsorted outer union Methode kein
Ergebnis liefern kann. Das Problem liegt hier beim hash-basierten Tagger, der ( noch )
nicht in der Lage ist overflows zu handhaben. Im Gegensatz dazu, kommt der sorted
outer union plan mit der Speichereinschränkung gut zurecht.
5.8. path outer union vs. node outer union
Wie bereits zuvor angekündigt, werden jetzt die beiden Methoden untersucht, die bei
ausreichend Speicherplatz, ähnliche Ergebnisse liefern. Obgleich der höheren Daten
Redundanz weist der path outer union Ansatz etwas bessere Werte auf, da hier weniger
Tupel erstellt werden müssen.
Ist der Speicher nicht ausreichend und gibt es einen hohen instance fan out, ist der node
outer union ca 3 Sekunden besser, der path Ansatz erstellt dann mehr redundante Daten
und erhält einen overhead beim Auslagern.
5.9. Zusammenfassung der erarbeiteten Ergebnisse
Drei wesentliche Aussagen können bzgl. der Messergebnisse getroffen werden :
1. XML-Dokumente gewinnt man am effizientesten mit inside the engine Ansätze
2. Wenn genügend Speicher vorhanden ist, um den kompletten Prozeß im
Hauptspeicher zu halten, so ist der unsorted outer union Ansatz ( inside & outside )
die effizienteste Lösung.
3. Falls der Speicher nicht ausreicht, sollte man die sorted outer union Methode
verwenden, da der relationale Sortierungsoperator sehr gut skaliert
6. Abschließender Kommentar und Ideen für zukünftige Arbeiten
Daten im WWW werden immer häufiger mittels XML veröffentlich, somit ist es nötig,
Lösungen zu erforschen, die es ermöglichen relationale Datenbanken in eine XML Form zu
konvertieren. Relationale Daten müssen strukturiert und getagged werden, dieses kann
innerhalb oder außerhalb der relationalen Maschine geschehen.
In diesem Dokument wurden verschiedene Ansätze vorgestellt und vor dem Hintergrund der
Effizienz diskutiert und beurteilt. Die vorgestellten Ansätze fordern keine
Neuimplementierung von Systemen, sondern bauen das bestehende SQL – System mit Hilfe
von erweiterten Funktionen aus, Applikationen und werden APIs können weiterverwendet.
Die Messungen dieses Experiments haben ergeben, daß es effizienter ist, alle Prozesse
innerhalb der Maschine ablaufen zu lassen, und daß der outer union Ansatz sich gegenüber
den anderen Alternativen als effizientester und stabilster durchgesetzt hat.
Die Weiterentwicklung von Parallelmaschinen, neue Laufzeitoperatoren innerhalb der
relationalen Maschine und Techniken der effizienten Speicherverwaltung können eine
Steigerungen der Effizienz bei outer union Ansätzen bringen.
Es ist desweiteren notwendig den tagger-Algorithmus derart zu modellieren, daß
verschachtelte Strukturen von beliebiger Tiefe kein Problem mehr darstellen. Den outer union
Ansatz könnte man eventuell so verändern, daß Informationen von ungebundenen Hierachien
aufgefaßt werden können unter Verwendung von Schlüsselspalten.
7. References
www.acm.org/sigmod/vldb/conf/2000/P065.pdf
Herunterladen