Kurzes Update zur Datenverfügbarkeit
VRML Syntax in Oracle-SQL-Relationen umsetzen
Update zur DatenverfügbarkeitWie in der letzten Zusammenfassung erwähnt, hatte ich eine Anfrage an einen Studenten gestellt, der angeblich eine komplette Repräsentation unseres zukünftigen Fakultätsgebäudes modelliert haben soll. Ich bekam diese dann freundlicherweise mit Verzögerung zur Verfügung gestellt. Es stellte sich jedoch heraus, daß es sich um das Modell das alten Gebäude, nicht des neuen handelte. Modell herunterladen (7MB)VRML Syntax in Oracle-SQL-Relationen umsetzenAllgemeines:
Diese Umsetzung der VRML97 Standatisierung richtet sich nach dem offiziellen VRML97 'Node reference' und den dazugehörigen Dokumenten.Ansatz:Die Hierarchie und Strukturierung der einzelnen Knoten als Baum ist in dieser Version noch NICHT repräsentiert. Es handelt sich hier um eine einfache Umsetzung der einzelnen Knoten mit ihren Attributen in Relationen. Dabei ist beachten, daß eventIn und eventOut Knoten nicht in der VRML-Datei gespeichert werden. Sie werden nur zur Laufzeit für die Ereignisverarbeitung genutzt (siehe Absatz 4.7 der ISO/IEC 14772:1-1997 Norm).
Ich definiere eigene Typen (die meist den Bezeichnungen der Norm folgen), sonst könnte man viele Daten nur als Text speichern und eine Abfrage wäre schwierig (man müßte das Ergebnis nochmal parsen). Als Typen werden Kollectionen vom gleichen Datentyp und Objekttabellen auf strukturierten Datentypen benutzt.
Die Integritätsbedingungen wurden soweit möglich in die Felddeklarationen zur Sicherheit aufgenommen, falls der Parser nicht auf Gültigkeit prüft. Leider ist es nur bei den einfachen Datentypen gelingen, sowohl DEFAULT-Wert Werte zu setzen, als auch alle Integritätsbedingungen. Bei strukturierten Datentypen ist es mir zwar gelungen, ein DEFAULT zu setzen, nicht aber auf Gültigkeit mittels CONSTRAINT zu prüfen. Bei Objecttabellen ist keines von beidem gelungen. :( Dies wäre noch eine Verbesserungsmöglichkeit für die Zukunft, obwohl fraglich ist, wie sinnvoll eine Konsistenzprüfung am BackEnd überhaupt ist. Eigentlich sollte das Frontend dies machen, da hier auch viel aussagekräftigere Fehlermeldungen und Hinweise erfolgen können.
Die Einschränkung, dass ein Wert nicht unendlich sein darf, habe ich nicht mit einer Bedingung abgefangen, da keine Eingabe die Repräsentation eines Wertes 'unendlich' erlaubt, somit nicht abgefangen werden kann.
Unklar ist noch, ob bei Feldern eine NULL-Eingabe erlaubt ist, wenn nichts über dieses gesagt wird.
Notation: die Benennung der Relationen folgt der VRML97-Definition, ebenso die Nummerierung SFx bedeutet 'Single Field Node' von Typ x MFy bedeutet 'Multi Field Node' vom Typ y die Constraints sind benannt und setzen sich aus 'check_' plus dem Feldname und der VRML-Knoten-Nummer zusammen '_typ' kennzeichnet einen Kolletkionstypen '_obj' kennzeichnet einen Objekttypen '_tab' kennzeichnet eine Objekttabelle Hinweis: einige Ausdrücke, die in der VRML Definition auftreten sind unter ORACLE reservierte Worte. Um dennoch eine größtmögliche Übereinstimmung zu erzielen, wurden diese Ausdrücke um ein '_' (Unterstrich) erweitert.
Da VRML keine 'flache' Struktur hat, sondern eine Hierarchie, die bis in die Datentypen hingeht, muß dieses auch in einer Datenbank repräsentiert werden. Die relationalen Systeme, wie es auch ORACLE ist, wurden dazu gemacht, um 'flache' Strukturen in Relationen ('Tabellen') abzubilden. Ab der Version 8 hat Oracle vermehrt objektorientierte Elemente in sein System eingebaut. Nun können eigene strukturierte Typen und Objekte definiert werden. Die machte ich mir zu Nutze und habe mir solche Datentypen definiert, die die VRML Datentypen am getreuesten abbilden können. Dabei gibt es zwei Möglichkeiten:Relationendefinition:Kollektion:
mehrere Werte eines Grunddatentyps setzen sich zu einem neunen Datentyp zusammen, z.B. besteht ein Vektor klassischerweise aus drei Zahlenwerten (für jede Dimension eine)
Vorteil: einfach zu definieren und zu verwenden
Nachteil: beim Definieren muß schon bekannt sein, wieviele Werte man speichern möchte und wie groß diese sind
Beispiele: CREATE TYPE SFVector_typ AS ARRAY(3) OF FLOAT;Typisierte Tabellen
ein Objekt wird definiert und die Objektstruktur legt eine Tabelle fest, in der jede Zeile einem Objekt entspricht
Vorteil: struktierte Objekte nachbildbar, keine Mengenbegrenzung
Nachteil: doppelte Arbeit beim Erzeugen (erst Object, dann Tabelle)
Beispiel: CREATE TYPE MFRotation_obj AS OBJECT(x FLOAT, y FLOAT, z FLOAT, a FLOAT);
CREATE TYPE MFRotation_tab AS TABLE OF MFRotation_obj;Nicht jeder Datentyp, der in VRML Verwendung findet, mußte so aufwändig nachmodelliert werden, vielfach konnten auch Basistypen verwendet werden. Eine Übersicht über die Datentypen und wie sie in SQL dargestellt werden, gibt es hier. Jede Relation bekommt außerdem einen eindeutigen Zähler mitgegeben, damit die in ihr enthaltenen Datensätze eindeutig benannt und auch referenziert werden können.
Eine Relation entspricht, wie schon oben erwähnt, einem Knotentypen mit seinen Attributen. Hier nur beispielhaft eine einfach und eine etwas kompliziertere Umsetzung eines VRML-Knotens:/* Type 6.43: Sphere */Hier wird eine Kugel mit einem Radius definiert und dabei geprüft, ob der angegebene Radius größer als Null ist.
CREATE TABLE Sphere (
id INTEGER PRIMARY KEY,
radius FLOAT DEFAULT 1.0 CONSTRAINT chk_radius CHECK(radius>0)
);Diesem Beispiel setzt den Knoten 'AudioClip' um, bei dem neben der Beschreibung und der Anfangs- und Endzeit auch spezifiziert werden kann, ob das Musikstück immer wieder von vorne anfängt zu laufen ('loop'), welche Tonhöhe ('pitch') gehalten werden soll und wo sich das Musikstück überhaupt befindet ('url'). loop stellt einen Wert dar, der nur wahr ('TRUE') oder falsch ('FALSE') sein kann. Um das sicher zu stellen, habe ich es erzwungen ('CONSTRAINT'). pitch darf nicht unter Null fallen, also auch hier die entsprechende Bedingung. Zu guter letzt noch 'url': Hier können mehrere Adressen im Netz angegeben werden, wo sich das Musikstück befinden könnte. Diese Adressen werden dann nacheinander von dem Browser, der die VRML-Szene darstellt, abgesucht. Leider legt niemand fest, wie viele Alternativen der VRML-Autor hier angeben kann. Es können zwei oder auch zweihundert sein. Daher kann ich nicht mehr mit Datentypen fester Länge arbeiten, sondern ich machen mit eine Tabelle in der Tabelle ('NESTED TABLE') zu nutze. Da Tabellen keiner Umfangsbegrenzung unterliegen (jaja, für die Klugscheißer: bei 2GB ist bei Oracle Schluß, ich weiß), können hier so viele Adressen abgelegt werden, wie man will. Untertabellen in Relationen werden als ganz normale Relation in der Datenbank gespeichert, müssen einen eindeutigen Namen tragen und hängen zwingend mit der 'Muttertabelle' zusammen. Wird diese gelöscht, verschwindet auch die eingebetete Relation aus der Datenbank.
/* Type 6.4: AudioClip */
CREATE TABLE AudioClip (
ID INTEGER PRIMARY KEY,
description VARCHAR(2000) DEFAULT '',
loop VARCHAR2(5) DEFAULT 'FALSE' CONSTRAINT check_loop_4 CHECK(loop IN ('TRUE','FALSE')),
pitch FLOAT DEFAULT 1.0 CONSTRAINT check_pitch_4 CHECK(pitch > 0),
startTime FLOAT DEFAULT 0.0,
stopTime FLOAT DEFAULT 0.0,
url MFString_tab
)
NESTED TABLE url STORE AS url_table_4;Auf diese Art wurden alle VRML-Konstrukte in Relationen umgesetzt (mit den o.g. Einschränkungen). Die fertige SQL-Scriptdatei kann man sich hier anschauen.