Modell mit vielen Abhängigkeiten untereinander...

Andre

Benutzer
Beiträge
14
Wir haben ein Datenmodell das sich sehr stark an einen Objektorientierten Ansatz anlehnt. So haben wir beispielsweise Tabellen für Geräte, Personen, Räume... die von einer Ressourcentabelle "erben" (Table per Type [TPT]), der wiederum allgemeine Informationen zugeordnet (z.B. Schlagwörter/Tags, Zusatzdaten, Dokumente...) werden. Mit der Zeit wurde von Kundenseite für immer mehr Datentypen die Zuordnung dieser allgemeinen Informationen gewünscht, und stark überspitzt geht es in die Richtung das wir eigentlich für nahezu alle Tabellen eine gemeinsame Basistabelle haben, auf dessen Ebene konfigurierbar bestimmte allgemeine Daten zugeordnet werden können (Bei diesen "allgemeinen" Daten handelt es sich ebenso um nicht nur eine Tabelle sondern mehrere).

Die Datenbank ist schon lange an die Grenzen gestoßen, das es zu viele Abhängigkeiten zu einzelnen Tabellen gab, so das wir an vielen Stellen die Beziehungen nicht mehr mittels Constraints absichern (und ich regelmäßig nacharbeiten muss, wenn mal wieder festgestellt wird das man im Code an einer Stelle dies auch übersehen hat, und wieder mal Datenleichen entstanden sind). Die bisherige "Datenbank" *hust* kennt weder Trigger noch STPs, so das man hier auch nichts auf DB-Seite machen konnte... damit soll nun aber Schluß sein, der Wechsel auf ein richtiges Datenbanksystem ist nun in der Planung (bedingt durch die Verbreitung auf Kundenseite wird es MS SQL Server).

Das stellt sich aktuell im wesentlichen wie folgt dar:

Code:
        TblObjekt <--> TblSchlagwort (und weitere allgemeingültige Tabellen)
        |               |
TblGeraet    TblRaum (und noch viele andere Tabellen die von TblObjekt "erben").

Nun stellt sich für mich hier dennoch die Frage was der sinnvollste Ansatz ist, wenn man wie bei uns auf der einen Seite viele Tabellen hat, die teilweise untereinander nichts oder nur wenig gemeinsam haben, auf der anderen Seite aber auch Tabellen mit allgemeinen/informativen Daten die möglichst vielen davon zugeordnet werden können. Für jede Möglichkeit eine eigene Zuordnungstabelle zu erstellen lässt die Tabellenanzahl in extreme Höhen schiessen, ob eine gemeinsame "Basistabelle" für die allgemeinen Zuordnungen der sinnvolle Ansatz ist, bezweifel ich aber eigentlich auch.

Mir persönlich (aber ich bin auch kein gelernter DB-Administrator) stellen sich hierbei mehrere Ansätze:

1. (schließe ich aus) Wirklich jeder Zuordnungsmöglichkeit hierbei eine eigene Verknüpfungstabelle zu spendieren. Dies halte ich weder von der Wartbarkeit noch der Übersicht für sinnvoll.

2. Alle Tabellen die eine Verknüpfung von allgemeinen Daten vorsehen, "erben" (wie bisher) von einer Basistabelle (nennen wir sie einmal TblObjekt), auf deren Ebene die allgemeinen Daten verknüpft werden (Objekt<->Schlagwort, Objekt<->Zusatzdatum...). Die Id dieser Basistabelle dient als Id der "abgeleiteten" Datensätze (z.B. ein Datensatz in der Personentabelle hat als Id die IdObjekt der TblObjekt). Die Beziehung der "Vererbung" wird wegen der hohen Anzahl nicht mit Constraints sondern über Trigger oder STP-Logik gelöst.

3. Alle Tabellen die eine Verknüpfung von allgemeinen Daten vorsehen, erhalten eine gemeinsam genutzte Id-Sequenz, die Verknüpfungstabelle entfällt, alle Abhängigkeiten werden komplett über Trigger oder STP-Logik simuliert.

Vielleicht gibt es aber noch ganz andere Ansätze.
 
Werbung:
Also deinen bisherigen Ansatz finde ich eigentlich nicht schlecht, ich bin mir nichtmal sicher ob eine andere Variante es wirklich besser macht. Ich wundere mich vor allem darüber, das ein Trigger schneller sein soll als FK Constraint. Da kann doch irgendwas nicht passen, der Trigger macht doch nichts anderes. Selbiges gilt natürlich für Umsetzung durch die Anwendung, hier kann eigentlich die DB nur schneller sein.

Ein Problem mit schlechten Indezies würde ich ausschließen, das würde auf jedenfall in allen Varianten greifen.

Welches DBMS kommt denn derzeit zum Einsatz? Löst vieleicht der Umstieg auf MSSQL schon das eigentliche Problem? Mag sein das euer jetziges DBMS hier eine Schwäche hat.

Über wieviele Einträge in der Objekte Tabelle reden wir hier? Unser DMS hat auch eine Tabelle für alle Objekte, mehrere Tabellen oder Partitionierung der selbigen ist meines Wissens nach nicht vorgesehen.
 
Also deinen bisherigen Ansatz finde ich eigentlich nicht schlecht, ich bin mir nichtmal sicher ob eine andere Variante es wirklich besser macht. Ich wundere mich vor allem darüber, das ein Trigger schneller sein soll als FK Constraint.

Es geht nicht um schneller, sondern um die Höchstbegrenzung von Constraints pro Tabelle. Auch wenn die bisherige *hust* Access-Datenbank sehr eingeschränkt ist, hat auch der MS SQL Server Obergrenzen - zumindest "empfohlene" (siehe "Foreign key table references per table" unter http://msdn.microsoft.com/en-us/library/ms143432.aspx ).

Welches DBMS kommt denn derzeit zum Einsatz? Löst vieleicht der Umstieg auf MSSQL schon das eigentliche Problem? Mag sein das euer jetziges DBMS hier eine Schwäche hat.

Der Umstieg wird zumindest bei dem derzeitigen DB-Schema (das aber über kurz oder lang notgedrungen noch wachsen wird) die Möglichkeit von der Umsetzung per "Table per Type [TPT]" her unterstützen. Ich frage mich dennoch ob dies aus DB-Sicht wirklich der beste Ansatz ist (wie gesagt bin ich kein DB-Admin, selbst wenn ich die meisten DB-Kenntnisse in unserer Firma habe).

Was etwas gegen den Ansatz sprechen könnte, hat mit der Entwicklerseite und dem verwendeten ORM zu tun. Wenn ich TPT verwende, dann muss ich alle Objekte über den Basistyp auswählen... http://weblogs.asp.net/manavi/archi...ode-first-ctp5-part-2-table-per-type-tpt.aspx
 
Wenn ich das richtig interpetiere kann man also 253 Fremdschlüssel in einer Tabelle definieren. Das reicht nicht?

Es geht mir nicht bloß um das "ist möglich", sondern ob es bezogen auf Datenbankdesign so auch sinnvoll und gut ist. Ich erinnere mich immer wieder an eine Firma zurück, mit einem Datenbankadministrator hatten (der im Gegensatz zu mir wirklich die Datenbank bis ins Detail kannte und wusste was für eine Datenbank eher schlecht und eher gut ist). Dieser hat regelmäßig Entwicklern gesagt, das man tunlichst nicht Objektorientiert beim Design der Datenbank vorgehen sollte, sondern das andere Ansätze für eine relationale Datenbank schlicht und ergreifend besser sind.

Aus meiner Entwicklersicht ist dieser Ansatz okay, aber ich meine Datenbankkenntnisse umfasst keine Optimierung von Datenbanken.
 
Es geht mir nicht bloß um das "ist möglich", sondern ob es bezogen auf Datenbankdesign so auch sinnvoll und gut ist.

Tabellen mit einer 3stelligen Anzahl Spalten halte zu faktisch 100% für FAIL. Mir geht es nur darum, daß Limits einer DB das eine sind.
Wer in die Nähe dieser Limits kommt, muß prüfen, ob a) die DB falsch ist oder b) er etwas falsch macht.

Ich rede wohlgemerkt von Limits wie Spaltenanzahl oder so, nicht von Limits a la 'das können wir auch nicht'.

Ich erinnere mich immer wieder an eine Firma zurück, mit einem Datenbankadministrator hatten (der im Gegensatz zu mir wirklich die Datenbank bis ins Detail kannte und wusste was für eine Datenbank eher schlecht und eher gut ist). Dieser hat regelmäßig Entwicklern gesagt, das man tunlichst nicht Objektorientiert beim Design der Datenbank vorgehen sollte, sondern das andere Ansätze für eine relationale Datenbank schlicht und ergreifend besser sind.

Ich hab bei einem Kunden auch schon Dinge gesehen, die gruselig waren, weil diese aus so einem OR-Mapper halt so rauskamen. Aber ich bin kein Entwickler, hier mag ich mich nicht zu sehr aus dem Fenster lehnen wollen ...

Wenn man a) eine DB nimmt, die das, was man braucht, kann und b) das Design sauber entwirft sollten bei einklich allen aktuellen DB-Systemen keine Probleme auftreten. Außer bei MySQL ;-)

PS.: PostgreSQL nennt sich Objekt-Relational, weil es auch so Dinge wie Vererbung kann (Inheritance), ich weiß nicht, ob Du sowas suchst und ob M$SQL das kann.
 
Also ich denke mal das hier single point of failure bei den FKs auf der Objekte Tabelle liegt. Wenn deine PK Spalte in Objekte dem PK in den jeweiligen Zusatztabellen entspricht und du z.B. beim Löschen eines Datensatzes per FK Constraint prüfst ob ein zugehöriger Datensatz in einer der Zusatztabellen existiert kann das ja aus sicht der DB in jeder der Zusatztabellen der Fall sein. Also muss die DB alle Tabellen prüfen. Ich denke hier liegt der Knackpunkt. Nicht wegen der Anzahl der FK Einschränkungen sondern weil du alle Tabellen abfragen musst.

Wenn die Anwendung für immer mehr unterschiedliche Objekte skalieren muss dann würde ich vieleicht doch ein anderes Vorgehen empfehlen:

In der Objekte Tabelle stehen nur Eigenschaften, die alle Objekte zwigend haben. Die speziellen Atribute stehen alle in einer anderen Tabelle die nur so definiert das es ein FK auf den Datensatz gibt, eine Spalte die den Datentypen definiert und eine Spalte für die eigentliche Information. Das zusammenkleistern übernimmt die Anwendung.

Beispiel:

ObjekteTabelle
ObjektID, Objekttyp, Objektbezeichnung
1, Auto, Herbert

ObejektAtributeTabelle
ObjektID, Maskenfeldbezeichnung,Datentyp,Einheit,Daten
1,Marke,Varchar,NULL,VW
1,Modell,Varchar,NULL,Golf
1,Generation,Varchar,NULL,II
1,Preis,Money,Euro,1000

Nachteile:
  • Die eigentliche Information hat immer den selben Datentypen. Hier kann man eventuell mehrere Spalten oder sogar mehrere Tabellen für unterschiedliche Datentypen nutzen um z.B. die Vorteile von Datumsfunktionen auch nutzen zu können.
  • Um alle Informationen zusammen zu kleistern bedarf es einer gewissen Logik. Die muss entweder die Anwendung umsetzen oder dynamisches SQL.

Vorteile:
  • Neue Objekttypen kommen ohne neue Tabellen aus oder Constraints aus. Keine Änderung an der DB.
  • Versionierung von Informationen leicht gemacht, es ist quasi schon eine Logtabelle.
 
Wenn die Anwendung für immer mehr unterschiedliche Objekte skalieren muss dann würde ich vieleicht doch ein anderes Vorgehen empfehlen:

Nennt sich EAV (http://en.wikipedia.org/wiki/Entity–attribute–value_model), verwendet z.B. Magento (Shopsoftware).
Die resultierenden SQL-Würmer sind gruselig, die Performance auch und die Hardwareanforderungen sehr hoch.

Ich könnte mir vorstellen, daß eine Mischung von relationalen Tabellen und einem Key-Value-Store sehr schnell sein könnte, und PG bietet mit HSTORE sogar einen Key-Value-Store - Datentypen an. Das ist in aktuellen Versionen (also ab 9.2) schon wirklich geil schnell, ich weiß aber auch, daß (vielleicht 9.4 oder erst später) da nochmals einen enormen Performance-Boost bringen wird (bei Interesse kann ich Vorträge der pgconf rauskramen)
 
Unser DMS nutzt es auch, ich wollte es mal erklären.

Unter Nachteile sollte vieleicht noch Performance fallen, wobei ich da eher keine Probleme mit habe. SQL Abfragen die Atribute kombinieren sind natürlich nervig.
 
Ich muss zugeben, dass ich das Problem des OP mangels Erfahrung mit solchen Monstern nicht ganz nachvollziehen kann. Daher möchte ich einfach meinen Eindruck wiedergeben der auf rein theoretischen Annahmen beruht.

Die Beschreibung des Modells klingt für mich wie eine Mischung aus OO-Stil und ER-Stil. Wobei allerdings die Nachteile beider Stile vereint werden. Daher viele Relationen(OO) gepaart mit vielen Verknüpfungen(ER). Die Anwendung erzeugt also nicht 1 Tupel pro Entity sondern viele mit Teilinformationen. Echte datenbankgestützte Vererbung ist natürlich ein anderes Thema. Nach meinen Informationen wird das Konzept von MS-SQL aber nicht unterstützt.

Was mich in dem Zusammenhang noch interessiert wäre ob eine angemessene Normalisierung stattfindet.
 
Die Beschreibung des Modells klingt für mich wie eine Mischung aus OO-Stil und ER-Stil. Wobei allerdings die Nachteile beider Stile vereint werden. Daher viele Relationen(OO) gepaart mit vielen Verknüpfungen(ER).
Beziehst du dich jetzt auf das HSTORE Modell (womit ich mich noch nicht befasst habe) oder auf EAV?

Ich denke der vorliegende Fall erfordert gar keine so perfekte Normalisierung. In der Objektorientieren Welt geht es ja mehr darum alle Informationen eines Objektes schnell laden zu können, weniger darum viele Objekte miteinander zu vergleichen. Der Vergleich bzw das finden ähnlicher Objekte scheint im wesentlichen über Schlagwörter zu laufen, oder fasse ich Andre da falsch auf?
 
Beziehst du dich jetzt auf das HSTORE Modell (womit ich mich noch nicht befasst habe) oder auf EAV?

Ich beziehe mich auf die Beschreibung des ursprünglichen Fragestellers. Objektorientiert bedeutet in einer Datenbank etwas völlig anderes als in der Programmierung. Als Programmierer arbeite ich mit Objekten um Spezialisierungen durch Vererbung einfacher zu gestalten und Code-Redundanzen zu vermeiden. In einer Datenbank besitzt eine Spezialisierung selbst alle Felder. Dadurch kann auf JOINS verzichtet werden und der physikalische Speicherplatzverbrauch wird minimiert. Erkauft wird das Ganze allerdings durch O(2^n) Relationen bei n Kindern.
 
Werbung:
Zurück
Oben