Datenbankdesignfrage
-
Hallo!
Ich habe ein Problem beim Datenbankdesign - für eine eigentlich sehr einfache Datenbank. Ich will mit der Datenbank Filme, Serien, Dokumentationen, allgemein also Aufzeichnungen, speichern. Diese verschiedenen Gerne haben ein Set gemeinsamer Eigenschaften, wie z.B. Titel, Sprache, aber auch Spezifische, wie z.B. die Staffel und Episodentitel bei Serien, der Originaltitel bei >eingedeutschten< Filmen, der Sender bei Fernsehaufzeichnungen oder der "Index" bei Mehrteilern. Ganz abgesehen davon, dass nicht immer alle Eigenschaften für alle Einträge vorhanden sein werden.
Die offensichtliche Lösung wäre, eine Tabelle zu haben, bei der für jede Eigenschaft eine Spalte angelegt wird. Mir wurde gesagt, dass z.B. auch RoR Klassenhierarchien auf diese Weise speichert und wenn man sich das mal überlegt, bietet das wirklich einige unschlagbare Vorteile: Man kann damit sehr einfach arbeiten und es müssen keine Daten serialisiert werden, was zu einer noch einfacheren Benutzung führt. Allerdings hat man je nachdem, wieviele Eigenschaften es mal werden, sehr viele Spalten, die zu weiten Teilen nur NULL beinhalten werden.
Im Gegensatz dazu gäbe es die Möglichkeit, drei Tabellen aufzusetzen:
Eine Tabelle, die die verschiedenen Typen von Eigenschaften enthält, also "Genre", "Jahr" usw.
Eine Tabelle die sich aus Eigenschaftentyp, Wert der Eigenschaft und Aufzeichnungs-ID zusammensetzt.
Eine Tabelle für die Aufzeichnungen, aufs Wesentliche reduziert.Allerdings müssten hierbei die Eigenschaften ggf. serialisiert werden. Die Typinformation geht dabei indirekt verloren (wobei man vom Eigenschaftentyp darauf schließten könnte) - aber in Datenbankabfragen verkompliziert es sich dann, nach Filmen zu suchen, die z.B. in den 90ern gedreht wurden.
Nach diesem Vorbericht nun zur entscheidenen Frage: Gibt es eine Art Muster, um so ein Problem eleganter zu lösen, oder muss ich auf einen der genannten Entwurfe zurückfallen?
Was mir noch einfiel, waren Tabellen, die jeweils nur eine Spalte haben und jeweils nur einen bestimmten Datentyp speichern. Also z.B. INT, TEXT oder DATETIME. Diese Tabellen könnten jeweils als Fremdschlüssel die Eigenschaft-ID bekommen. Diese ID wäre in allen drei Tabellen jeweils eindeutig, mit joins könnte man dann typisierte Daten "dynamisch" einfügen. Allerdings wüsste ich nicht, wie man das auf INSERTS erweitern könnte. Dort muss dann ja eine konkrete Tabelle bekannt sein. Das liese sich im Notfall codetechnisch lösen, dann könnte man zumindest noch bei den Abfragen einen kleinen Vorteil rausholen. Aber wirklich gefallen tut mir das wegen dieser Inkonsistenz bei den INSERTS dann doch wieder nicht.
Vorschläge? :xmas1:
-
fuer jeden Typ eine separate Tabelle (also eine fuer Serien, eine fuer Spielfilme, usw).
Alternativ kannst du alles in eine packen, wenn du merkst, dass die Spalten sich zu sehr gleichen. Filme haben dann halt eine Episodenanzahl von 1. Den Typ kannst du ja zusaetzlich mit ablegen.
-
Meine Erfahrung mit DB-Design ist sehr begrenzt, hier mal meine Gedanken dazu:
Eine Tabelle für alle Aufzeichnungen mit optionalen Feldern ist die einfachste Lösung.
Eine Tabelle für jeden Typ ist dann unpraktisch, wenn man über alle Aufzeichnungen Abfragen erstellt, da dann über alle Tabelle gejoint werden muss.
Ich würde eine Lösung mit einer Tabelle für Attribute aller Aufzeichnungen anlegen. Die typabhängigen Elemente gibt's dann die Möglichkeit, eigenständige Tabellen mit allen Plichtfeldern des Typs oder die schon beschrieben Attributtabelle zu verwenden.Bei dem Attributtabellenansatz kann allerdings nicht ermittelt werden, ob alle notwendigen Attribute für einen Aufzeichnungstyp gesetzt sind. Hier muss man der Datenpflege etwas sorgfältiger sein. Außerdem kann die Tabelle recht schnell wachsen.
Ich würde die Lösung mit einer Tabelle für alle Aufzeichnungen und zusätzlichen Typ-Tabellen bevorzugen.
Grüße
don_basto
-
Gibt es eine Art Muster, um so ein Problem eleganter zu lösen, oder muss ich auf einen der genannten Entwurfe zurückfallen?
Naja, es gibt viele Möglichkeiten.
Du kannst die "Entity_ID, Property_ID, Property_Value" Version verwenden, und für bestimmte Properties die in Suchen häufig vorkommen Indexed-Views erstellen - was SELECTs deutlich schneller machen kann.Die erste Version die du erwähnt hast ist auch sehr verbreitet, weil sie sehr einfach ist (Queries werden nicht grundlos verkompliziert).
----
Dann gibt es AFAIK noch einen Haufen "nicht-standard-SQL" Datenbanken die diverse Dinge können die eine normale SQL Datenbank nicht kann. Evtl. gibt es da auch genau so Systeme wo man mehr oder weniger frei diverse Eigenschaften mit Entities vernküpfen kann, ohne diese zu Strings serialisieren zu müssen.
Was es auch gibt sind XML "Datenbanken" bzw. XML-Indexing-Engines. Du legst deine Daten dann einfach in XML Files ab, und lässt die Engine dann einen Index darüber erstellen. Auf diesen Index kann man dann (mit einer eigenen Suchsprache die mit SQL garnixmehr zu tun hat) Abfragen ausführen.
Und es gibt "Zwischenlösungen" wie z.B. die XML Spalten die MS-SQL Server unterstützt. Da drinnen kannst du auch Daten in XML Form ablegen, die Spalte mit einem XML-Index indizieren, und dann mit eigenen XML-Query-Funktionen in z.B. einer WHERE Clause oder auch im Select direkt darauf zugreifen.