Letzte Woche war ich auf der diesjährigen DOAG-Konferenz (Vortragsunterlagen zum Download). Bei einem der letzten Vorträge ging es um „Flexible Schnittstellen für Data Warehousing auf XML-Basis“, wobei mich die Kombination aus „flexibel“ und „XML“ angesprochen hat. Im Vortrag stellte Herr Bauer von der MT AG [wikipop]XML[/wikipop]-Verarbeitung mit dem Oracle Warehouse Builder vor, bei der letztendlich XMLTYPE für die interne Repräsentation der Daten verwendet wird.
In der Diskussion habe ich erwähnt, dass man alternativ eine allgemeine Tabelle für hierarchische Daten mittels des in Oracles Java-VM enthaltenen SAX-Parsers füllen könne. Das traf auf reges Interesse, besonders wegen der Schnelligkeit und den ressourcen-schonenden Eigenschaften des SAX-Parsers, die mir beim Verarbeiten von XML positiv aufgefallen sind.
Bevor ich aber zum SAX-Parser komme, noch ein paar Betrachtungen zu XML einerseits und relationalen Daten andererseits sowie zu effektiven Tabellenstrukturen für hierarchische Daten.
XML und SQL-Datensätze – ein ungleiches Gespann
XMLTYPE und DBMS_XMLDOM sind nicht gerade ideal für die fachliche Verarbeitung von XML-Daten. Bei XMLTYPE stört vor allem die Notwendigkeit, eine Schemadefinition ablegen zu müssen, wenn Oracle effektiv in einer XMLTYPE-Instanz navigieren soll – sonst ist XMLTYPE nur ein CLOB. Außerdem ist XMLTYPE [wikipop]XPath[/wikipop]-orientiert und damit nicht besonders geeignet für stures Durchmustern des Baums. Verwendet man dagegen DBMS_XMLDOM, gehen einem schnell Schreibaufwand und die nötigen Casts (z. B. MakeElement) auf die Nerven, außerdem sind DOM-Strukturen sehr speicheraufwändig. Suchoperationen a la XPath gibt’s auch nicht.
Grundsätzlich aber stört mich die Diskrepanz zwischen XML und den (Tabellen-/View-/…)-Datensätzen in PL/SQL. In den meisten Fällen sind nämlich die XML-Leaf-Elemente Attribute eines Datensatzes, während ihre jeweiligen XML-Elternelemente einen Datensatz als Ganzes repräsentieren.
[sql]
create table MUPPETS
as select 1 ID, ‚Kermit‘ NAME, ‚frog‘ TYPE, ‚green‘ COLOR
from dual;
[/sql]
kann in XML so aussehen:
[xml]
<MUPPETS>
<MUPPET ID="1"> <!– oder doch lieber <ID>1</ID>? –>
<NAME>Kermit</NAME>
<TYPE>frog</TYPE>
<COLOR>green</COLOR>
</MUPPET>
</MUPPETS>
[/xml]
oder so dargestellt werden:
[xml]
<MUPPETS>
<MUPPET ID="1" NAME="Kermit" TYPE="frog" COLOR="green"/>
</MUPPETS>
[/xml]
Jeder XML-Fan findet die zweite Variante natürlich böse und häßlich, obwohl sie aus Datensicht die eindeutigere ist – in der Element-Darstellung ist nämlich nicht klar, dass das Element color nur einmal vorkommen darf und Unter-Datensätze sind nicht deutlich von den „Spalten“-Werten eines Datensatzes abgesetzt (und ja, es gibt Schema-Beschreibungen):
[sql]
create table INSTRUMENTS
as select 1 ID,
(select ID from MUPPETS where NAME = ‚Kermit‘) MUPPET_ID,
‚trumpet‘ NAME, ‚brass‘ TYPE
from dual;
[/sql]
führt in der XML-Element-Variante zu
[xml]
<MUPPETS>
<MUPPET id="1">
<NAME>Kermit</NAME>
<TYPE>frog</TYPE>
<COLOR>green</COLOR>
<INSTRUMENT ID="1">
<NAME>trumpet</NAME>
<TYPE>brass</TYPE>
</INSTRUMENT>
</MUPPET>
</MUPPETS>
[/xml]
In der Attribut-Variante entsteht eigentlich klarer (und kürzer):
[xml]
<MUPPETS>
<MUPPET ID="1" NAME="Kermit" TYPE="frog" COLOR="green">
<INSTRUMENT ID="1" NAME="trumpet" TYPE="brass"/>
</MUPPET>
</MUPPETS>
[/xml]
Unabhängig von der XML-Form: Wird ein Dokument z. B. über DOM eingelesen (egal ob in oder außerhalb der DB, mit PL/SQL oder Java oder C …),
- tauchen auch noch jede Menge leere Textknoten durch das Pretty-Printing auf, die beim Navigieren über den Baum nur stören,
- müssen mehrere XML-Elemente zu einem fachlichen Objekt/Datensatz zusammengeführt werden,
- müssen u. U. Zahlen-, Datums- und Zeitstempel-Werte in die Datentypen der jeweiligen Programmierumgebung überführt werden (SQL: NUMBER, DATE, TIMESTAMP, Java: java.util.Date …),
- müssen Mapping- und Listen-Strukturen erkannt werden.
Alles in allem finde ich XML nicht besonders schön für die Datenrepräsentation. Das werden vor allem [wikipop]JSON[/wikipop]- und [wikipop]YAML[/wikipop]-Anhänger bestätigen, s. u. a. Stackoverflow und nachfolgenden Links.