Mapping von Klassenhierarchie auf Tabellen
-
Hallo.
Ich beschäftige mich gerade mit einem OR-Mapper (nHibernate) und bin auf die drei gängigen Abbildungen von Klassenhierarchien auf Tabellen gestoßen:
1. Tabelle pro konkreter Klasse
2. Tabelle pro Klasse (abstrakt und konkret)
3. Tabelle pro HierarchieMich würde interessieren was ihr bevorzugt und aus welchem Grund. Auch, welche Erfahrungen ihr mit den Strategien gemacht habt.
Strategie eins zerstört die Polymorphie. Da müsste man wirklich sicher sein, dass sie nicht mehr benötigt wird.
Strategie zwei erhöht die Komplexität der Abfragen massiv. Es sind Joins notwendig.
Ich tendiere also zu der dritten Möglichkeit. Die Polymorphie bleibt erhalten und es sind keine teuren Joins bei Abfragen notwendig. Andererseits müssen alle Datenspalten nullable sein. Das sehe ich nicht als sehr problematisch an. Gibt es weitere Nachteile?
Gruß, µ
-
Unverschämterweise pushe ich den Thread jetzt.
Ihr müsst doch auch ständig vor dem Problem stehen, Objekthierarchien auf Tabellen abzubilden, oder?
-
Das kommt bei mir eher selten vor Wenn schon, dann muß ich eher den umgekehrten Weg gehen und vorhandene Tabellen in eine Klassenstruktur quetschen.
-
µ schrieb:
Ihr müsst doch auch ständig vor dem Problem stehen, Objekthierarchien auf Tabellen abzubilden, oder?
Ich meide es. Entweder ist es eine betriebliche Anwendung und dann bleiben die Daten in Tabellen und ich betreibe keine Polymorphie. Oder ich betreibe Polymorphie und stopfe dann keine Datenbank drunter.
-
Gut das Thema scheint überbewertet und in der Praxis nur selten vertreten zu sein.
Ich arbeite bisher auch Tabellenorientiert. Aber es fühlt sich nicht gut an. Es schrammt am objektorientierten Code vorbei.
-
µ schrieb:
Auch, welche Erfahrungen ihr mit den Strategien gemacht habt.
Ich habe mit Strategie (2) ein einem Projekt relativ schlechte Erafhrungen gemacht, und zwar was die Performance angeht. Anwenden lässt es sich sauber, aber die JOINs über 2, 3, 4 Tabellen kosten einfach sehr viel.
Auch die vielen Referential-Integrity-Constraints tun weh. Ein Bulk-Insert mit 1000 Zeilen in eine halbwegs einfache Tabelle in einer Datenbank mit ca. 10GB Grösse = 10-20 Sekunden CPU-Zeit.Zu Strategie (3): das kann gut funktionieren, kann aber auch mächtig in die Hose gehen. Angenommen du hast eine Klasse die mächtig viele Member hat, aber relativ wenig Instanzen, und eine, die sehr wenige Member hat, dafür aber massiv viele Instanzen. Wenn du das mit Strategie (3) auf einem DBMS machst das NULL Werte nicht "komprimiert" abspeichern kann, dann bläht das den Table massiv auf. MSSQL 2008 Standard kann das z.B. NICHT (Mann, hab ich mich geärgert wie ich rausbekommen habe dass das Feature auf die Enterprise-Version beschränkt ist!).
Wenn du es dagegen mit Strategie (1) machst, fällt dieses Problem weg. Auch spart man sich dadurch ein "Entity-Type" Feld, und man kann besser mit Referential-Integrity-Constraints arbeiten (was bei Strategie (3) ja nicht so toll funktioniert). Das selbe gilt für CHECK Constraints.
Auch finde ich dass das die Datenbank mit Strategie (1) "übersichtlicher" wird - in dem Sinn dass man schneller sieht was es alles für verschiedene Entities gibt.Ich würde im Moment also eher zu Strategie (2) tendieren: ein Table pro konkretem Entity-Typ. Ist auch denke ich am nähesten beim "tabellenorientiert" Arbeiten.
-
Interessant
-
hustbaer schrieb:
µ schrieb:
Auch, welche Erfahrungen ihr mit den Strategien gemacht habt.
Ich habe mit Strategie (2) ein einem Projekt relativ schlechte Erafhrungen gemacht, und zwar was die Performance angeht. Anwenden lässt es sich sauber, aber die JOINs über 2, 3, 4 Tabellen kosten einfach sehr viel.
[...]
Ich würde im Moment also eher zu Strategie (2) tendieren: ein Table pro konkretem Entity-Typ. Ist auch denke ich am nähesten beim "tabellenorientiert" Arbeiten.Kann es sein, daß du dich da vertippt hast?
@µ: Wie gesagt, bei uns waren zuerst die Datenbank-Strukturen da und später hat ein (Ex)Kollege dafür Mapping-Klassen gebaut. Von der Struktur her sind die meisten Tabellen eigenständig, aber wir haben auch Tabellenstrukturen, die der Variante 1 (die sind sogar teilweise in den nHibernate-Klassen verpackt) oder Variante 3 (haben wir für den Teil, den wir mit C# nutzen, noch nicht gebraucht) entsprechen.