2009-08-14 12 views
5

Ich entwerfe eine neue Labordatenbank mit VIELEN Typen meiner Haupteinheiten.Vererbung im Datenbankdesign

Die Tabelle für jede Entität enthält Felder, die allen Typen dieser Entität gemeinsam sind (entity_id, created_on, created_by usw.). Ich werde dann die konkrete Vererbung verwenden (separate Tabelle für jeden eindeutigen Satz von Attributen), um alle verbleibenden Felder zu speichern.

Ich glaube, dass dies das beste Design für die Standard-Datentypen ist, die täglich durch das Labor kommen. Oft haben wir jedoch spezielle Proben, die oft mit spezifischen Werten versehen sind, die der Urheber gespeichert haben möchte.

Frage: Wie soll ich spezielle (nicht standardisierte) Arten von Entitäten modellieren?

Option 1: Verwendung entity-Wert für spezielle Felder
einer Tabelle (entity_id, attribute_name, numerical_value) würden alle Daten für jede spezielle Einheit halten.
+ Weniger Tabellen.
- Kann kein bestimmtes Attribut erfordern.
- Muss Zeilen in Spalten umwandeln (pivotieren), was ineffizient ist.

Option 2: Strikte konkrete Vererbung.
Erstellen Sie separate Tabelle für jeden einzelnen Sonderfall.
+ Folgt in Übereinstimmung mit allen anderen Regeln
- Overhead von vielen Tabellen mit nur ein paar Zeilen.

Option 3: Konkrete Vererbung mit speziellen Tabellen unter einem anderen Benutzer.
Legen Sie alle speziellen Tabellen unter einem anderen Benutzer.
+ Hält alle Sonder- und Standardtabellen getrennt.
+ Leichtere Suche nach gängigen Standardtabellen in einer Liste ohne Suche in allen Sondertabellen.
- Overhead von vielen Tabellen mit nur ein paar Zeilen.

+1

Viele Tabellen mit wenigen Zeilen schneiden wahrscheinlich besser ab als eine Entity-Value-Tabelle, besonders wenn sie groß wird. Und sie sind viel einfacher abzufragen. – HLGEM

Antwort

9

Tatsächlich wird das von Ihnen beschriebene Design (gemeinsame Tabelle plus subtypspezifische Tabellen) Class Table Inheritance genannt.

Concrete Table Inheritance würde alle allgemeinen Attribute in den Subtype-Tabellen dupliziert haben, und Sie würden keine Supertype-Tabelle wie Sie jetzt haben.

Ich bin stark gegen EAV. Ich betrachte es als SQL-Antipattern. Es mag wie eine elegante Lösung erscheinen, weil es weniger Tische benötigt, aber Sie bereiten sich später für viele Kopfschmerzen vor. Sie haben ein paar der Nachteile erkannt, aber es gibt viele andere. IMHO, EAV wird nur dann angemessen verwendet, wenn Sie absolut nicht müssen eine neue Tabelle erstellen, wenn Sie einen neuen Subtyp einführen, oder wenn Sie eine unbegrenzte Anzahl von Subtypen haben (z. B. Benutzer können neue Attribute ad hoc definieren).

Sie haben viele Subtypen, aber immer noch eine endliche Anzahl von ihnen, wenn ich also dieses Projekt machen würde, würde ich bei Class Table Inheritance bleiben. Sie haben möglicherweise wenige Zeilen für jeden Subtyp, aber zumindest haben Sie die Gewissheit, dass alle Zeilen in jedem Subtyp die gleichen Spalten haben. Sie können NOT NULL verwenden, wenn Sie SQL-Datentypen verwenden, referenzielle Integritätsbedingungen verwenden können. etc.Aus relationaler Sicht ist es ein besseres Design als EAV.

Eine weitere Option, die Sie nicht erwähnt haben, heißt Serialized LOB. Das heißt, fügen Sie eine BLOB-Spalte für eine semi-strukturierte Auflistung von benutzerdefinierten Attributen hinzu. Speichern Sie XML, YAML, JSON oder Ihre eigene DSL in dieser Spalte. Sie können einzelne Attribute aus diesem BLOB nicht einfach mit SQL analysieren, Sie müssen den gesamten BLOB zurück in Ihre Anwendung holen und einzelne Attribute im Code extrahieren. In gewisser Weise ist es weniger praktisch. Aber wenn das Ihre Datennutzung befriedigt, dann ist daran nichts falsch.

+0

Eigentlich ist mein Design eine Mischung aus Klasse und Beton. Es verwendet die Klassenebene für Felder, die allen Typen gemeinsam sind, und die konkrete Ebene für alle übrigen Felder (von denen viele für mehrere Typen gelten). – Steven

+0

Ich folge vielleicht nicht dem, was du sagst, aber es klingt, als würdest du die Klassenvererbung genau beschreiben. –

+0

Mein Design würde genau zwei Ebenen haben. Die Hauptebene (eine Tabelle) enthält Felder, die allen Typen gemeinsam sind. Die zweite Ebene (viele Tabellen) hat eine Tabelle für jeden Typ, Zeitraum. Auch wenn einige Typen einige Felder gemeinsam haben, habe ich keine dritte (oder höhere) Ebene, die für die Vererbung erforderlich wäre, um vollständig auf Klassenebene zu sein. – Steven

1

Ich denke, es hängt hauptsächlich davon ab, wie Sie diese Daten verwenden möchten.

Zunächst sehe ich nicht den Vorteil von Option 3 gegenüber Option 2. Ich denke, Trennung der speziellen Tabellen in einem anderen Schema wird Ihre Anwendung schwieriger zu pflegen, vor allem, wenn später Gemeinsamkeiten zwischen 'Special gefunden werden Werte'. Als weitere Option würde ich sagen: - Speichern Sie die speziellen Werte in einem XML-Fragment (oder Blob). Die meisten Datenbanken haben heutzutage die Möglichkeit, XML-Strukturen abzufragen, sodass Sie ohne viele zusätzliche Tabellen Ihre Flexibilität für einen kleinen Leistungseinbruch behalten würden.

Wenn Sie alle speziellen Werte in eine Tabelle eingeben, erhalten Sie eine sehr spärliche Tabelle. Die meisten normalen DBMS können nicht so gut damit umgehen, aber es gibt einige Implementierungen, die darauf spezialisiert sind. Davon könnten Sie profitieren.

Müssen Sie häufig die Schlüssel/Wert-Paare abfragen? Wenn Sie im Grunde über die entry_id auf diese Tabelle zugreifen, denke ich, dass eine Schlüsselwerttabelle kein schlechtes Design ist. Ein zusätzlicher Index für die kay-Spalte könnte Ihnen sogar helfen, wenn Sie spezielle Werte abfragen müssen. Wenn Sie eine Anwendungsebene über Ihrer Datenbank erstellen, wird die Schlüsselwerttabelle auf einer Map- oder Hash-Struktur abgebildet, die ebenfalls problemlos verwendet werden kann.

Es hängt auch von den verschiedenen Arten von Werten ab, die Sie speichern möchten. Wenn es viele verschiedene Typen gibt, auf die leicht zugegriffen werden kann (statt in XML/Character-String serialisiert/deserialisiert zu werden), möchten Sie vielleicht den Typ in einer separaten Spalte speichern, aber das wird normalerweise zu einem sehr komplizierten Design führen.

Hoffe das hilft (ein bisschen).

-Maarten

+0

Warum sollte Oracle nicht mit spärlich gefüllten Tabellen umgehen können? Laut dieser Website http://highscalability.com/stack-overflow-architecture können sie. – tuinstoel

1

Oracle kann mit spärlich gefüllten Tabellen ziemlich gut umgehen. Ich denke, dass Sie einen ähnlichen Ansatz verwenden können, wie das Unternehmen Salesforce verwendet. Sie verwenden Tabellen mit vielen Spalten, sie erstellen Spalten, wenn sie benötigt werden. Sie können diese Spalten viel besser indizieren als ein eav-Modell.

So ist es flexibel, aber es ist besser als ein EAV-Modell.

lesen: Ask Tom 1, Ask Tom 2, High Scalabilty und SalesForce.

1

Die "Option 1" -Muster werden auch als "Universal Relation" bezeichnet. Auf den ersten Blick scheint es eine Abkürzung zu sein, um die Datenmodellierung nicht schwierig zu machen. Es handelt mit müheloser Datenmodellierung, weil es nicht in der Lage ist, einfaches Auswählen, Aktualisieren und Löschen ohne wesentlich mehr Aufwand durchzuführen, als es mit einem eher üblichen Datenmodell mit mehreren Tabellen möglich wäre.

Verwandte Themen