Sie haben mindestens diese fünf Optionen zum Modellieren der von Ihnen beschriebenen Typhierarchie:
Vererbung einzelner Tabellen: Eine Tabelle für alle Produkttypen mit genügend Spalten, um alle Attribute aller Typen zu speichern. Dies bedeutet viele Spalten, von denen die meisten in einer bestimmten Zeile NULL sind.
Vererbung von Klassentabellen : Eine Tabelle für Produkte, in der Attribute gespeichert sind, die allen Produkttypen gemeinsam sind. Dann eine Tabelle pro Produkttyp, in der Attribute gespeichert sind, die für diesen Produkttyp spezifisch sind.
Vererbung konkreter Tabellen : Keine Tabelle für allgemeine Produktattribute. Stattdessen eine Tabelle pro Produkttyp, in der sowohl allgemeine Produktattribute als auch produktspezifische Attribute gespeichert sind.
Serialisiertes LOB : Eine Tabelle für Produkte, in der Attribute gespeichert sind, die allen Produkttypen gemeinsam sind. In einer zusätzlichen Spalte wird ein BLOB mit halbstrukturierten Daten in XML, YAML, JSON oder einem anderen Format gespeichert. In diesem BLOB können Sie die für jeden Produkttyp spezifischen Attribute speichern. Sie können ausgefallene Designmuster verwenden, um dies zu beschreiben, z. B. Fassade und Andenken. Unabhängig davon, ob Sie einen Blob von Attributen haben, die in SQL nicht einfach abgefragt werden können. Sie müssen den gesamten Blob zurück zur Anwendung holen und dort sortieren.
Entity-Attribute-Value : Eine Tabelle für Produkte und eine Tabelle, die Attribute anstelle von Spalten in Zeilen umwandelt. EAV ist kein gültiges Design in Bezug auf das relationale Paradigma, aber viele Leute verwenden es trotzdem. Dies ist das "Eigenschaftenmuster", das in einer anderen Antwort erwähnt wird. Weitere Fallstricke finden Sie in anderen Fragen mit dem eav-Tag auf StackOverflow .
Ich habe mehr darüber in einer Präsentation, Extensible Data Modeling, geschrieben .
Zusätzliche Gedanken zu EAV: Obwohl viele Leute EAV zu bevorzugen scheinen, tue ich das nicht. Es scheint die flexibelste und daher die beste Lösung zu sein. Beachten Sie jedoch das Sprichwort TANSTAAFL . Hier sind einige der Nachteile von EAV:
- Keine Möglichkeit, eine Spalte obligatorisch zu machen (entspricht
NOT NULL
).
- Keine Möglichkeit, SQL-Datentypen zum Überprüfen von Einträgen zu verwenden.
- Keine Möglichkeit sicherzustellen, dass Attributnamen konsistent geschrieben werden.
- Es gibt keine Möglichkeit, einen Fremdschlüssel auf die Werte eines bestimmten Attributs zu setzen, z. B. für eine Nachschlagetabelle.
- Das Abrufen von Ergebnissen in einem herkömmlichen Tabellenlayout ist komplex und teuer, da Sie
JOIN
für jedes Attribut Folgendes tun müssen, um Attribute aus mehreren Zeilen abzurufen.
Der Grad an Flexibilität, den EAV Ihnen bietet, erfordert Opfer in anderen Bereichen, wodurch Ihr Code wahrscheinlich so komplex (oder schlechter) wird, als es gewesen wäre, um das ursprüngliche Problem auf konventionellere Weise zu lösen.
In den meisten Fällen ist ein solches Maß an Flexibilität nicht erforderlich. In der Frage des OP zu Produkttypen ist es viel einfacher, eine Tabelle pro Produkttyp für produktspezifische Attribute zu erstellen, sodass zumindest für Einträge desselben Produkttyps eine konsistente Struktur erzwungen wird.
Ich würde EAV nur verwenden, wenn jede Zeile möglicherweise einen bestimmten Satz von Attributen haben muss. Wenn Sie eine begrenzte Anzahl von Produkttypen haben, ist EAV übertrieben. Class Table Inheritance wäre meine erste Wahl.
Update 2019: Je mehr Leute JSON als Lösung für das Problem "Viele benutzerdefinierte Attribute" verwenden, desto weniger gefällt mir diese Lösung. Dies macht Abfragen zu komplex, selbst wenn spezielle JSON-Funktionen verwendet werden , um sie zu unterstützen. Das Speichern von JSON-Dokumenten erfordert viel mehr Speicherplatz als das Speichern in normalen Zeilen und Spalten.
Grundsätzlich ist keine dieser Lösungen in einer relationalen Datenbank einfach oder effizient. Die ganze Idee, "variable Attribute" zu haben, widerspricht grundsätzlich der relationalen Theorie.
Es kommt darauf an, dass Sie eine der Lösungen auswählen müssen, auf deren Grundlage Ihre App am wenigsten schlecht ist . Daher müssen Sie wissen, wie Sie die Daten abfragen, bevor Sie ein Datenbankdesign auswählen. Es gibt keine Möglichkeit, eine Lösung auszuwählen, die "am besten" ist, da eine der Lösungen für eine bestimmte Anwendung möglicherweise am besten geeignet ist.