Möchte man hierarchische Daten ablegen - wie z.B. Organisationsstrukturen in Unternehmen, so war das Standard-Vorgehen dazu bisher, 2 Felder zu verwenden - zunächst die Id des eigentlichen Elements und in einem weiteren Feld die Id des Elternknotens.
Damit lassen sich Abfragen wie: "Wer ist direkter Vorgesetzter des Mitarbeiters X?" oder "Welche Mitarbeiter sind direkt dem Vorgesetzten Y unterstellt?" recht einfach beantworten. Umfangreichere Aussagen wie: "Was sind alle direkten und indirekten Mitarbeiter des Managers X?" oder "Wer ist Ebene-3-Manager des Mitarbeiters Y?" sind damit schon schwieriger zu ermitteln.
Nun kommt der HierarchyId-Datentyp ins Spiel. Mit ihm können solche Zusammenhänge dargestellt und einfach abgefragt werden. Als Besonderheit gilt es zu beachten, dass dieser Datentyp als CLR-Datentyp implementiert ist, der allerdings auch dann zur Verfügung steht, wenn CLR-Integration deaktiviert ist. Daraus resultierend leitet sich auch die Darstellung der Funktionen ab. Dazu aber später mehr. Zunächst möchte ich die oben gezeigte Struktur mit diesem Datentyp aufbauen. Dazu erstelle ich eine neue Tabelle.
Im nächsten Schritt wird diese mit Daten gefüllt.
Lässt man sich nun die Daten einmal anzeigen, ergibt sich folgendes Bild:
Man erkennt, dass die Daten vorliegen - allerdings ist OrgNode eine hexadezimale Darstellung, die nicht ganz so benutzerfreundlich ist. Dafür gibt es Abhilfe, denn die Methode ToString gibt die kanonische Darstellung des OrgNodes zurück:
Nun erkennt man die hierarchischen Beziehungen schon besser.
Um die Vorteile auch komplett ausnutzen zu können, sollte man einen Blick auf die Methoden des HierarchyId-Datentyps werfen:
- GetRoot(): ermittelt den Hauptknoten
- GetAncestor(n): ermittelt den n-ten Vaterknoten
- GetDescendant(child1, child2): ermittelt Kindknoten
- GetLevel(): ermittelt die Hierarchieebene
- IsDescendantOf(): ermittelt, ob eine hierarchische Beziehung (ist y Kind von x) zwischen 2 Knoten besteht
- ToString(): Konvertierung in die kanonische Form
- Parse(): Konvertierung aus der kanonischen Form
- GetReparentedValue(): nützlich zum Umhängen von Teilstrukturen
Spalten des Datentyps HierarchyId achten nicht selbst auf die Eindeutigkeit. Aus diesem Grund ist es sinnvoll, einen eindeutigen Index auf die Spalte zu legen. Je nach Anwendungsfall unterscheidet man hier Depth-First-Index und Breadth-First-Index. Beim Depth-First-Index wird zuerst in die Tiefe gegangen - also zuerst alle Kindelemente des Knotens 1 indiziert, bevor zu Knoten 2 übergegangen wird. Beim Breadth-First-Index wird Ebene für Ebene indiziert.
Das Anlegen eines Depth-First-Index ist recht trivial - dazu indiziert man einfach eine bestehende HierarchyId-Spalte.
Für die Anlage eines Breadth-First-Indexes benötigt man noch eine zusätzliche Spalte in der Tabelle, in der der Level persistiert und die dann in den Index mit einbezogen wird.
Hallo, ich versuche gerade ein Java Produkt (bis jetzt lief alles mit Oracle) an MSSQL Server anzupassen. Einer der Aufgaben ist Hierarchischen Queries von Oracle optimal für MSSQL zu implementieren. Die möglichkeit mit den zwei Spalten kenne ich schon, leider ist das performancemäßig nicht so gut, deswegen habe ich mir überlegt der neue Datentyp HIERARCHYID zu nehmen. Leider kann ich keine Implementierung für JDBC finden. So meine Frage ist: Ist der Datentyp nur für CLR implementiert oder kann man das auch mit JDBC benutzen?
Ich werde mich auf jede Hilfe freuen.
Gruß
Hallo, soweit ich weiß, unterstützt der aktuelle JDBC-Treiber hierarchyId nicht. Mit der letzten Version sind zwar Features wir Unterstützung für datetime2 und datetimeoffset hinzugekommen, aber hierarchyId war leider nicht dabei
(s. http://msdn.microsoft.com/de-de/library/aa342325.aspx)
Gruß Martin
Danke für die schnelle Antwort Martin! Das ist natürlich ärgerlich, dass der Datentyp nicht unterstützt ist. Hmm trotzdem danke.