Wie eine Produkttabelle entwerfen für viele Arten von Produkten, wobei jedes Produkt viele Parameter hat

StackOverflow https://stackoverflow.com/questions/695752

Frage

Ich habe nicht viel Erfahrung in der Tabelle Design. Mein Ziel ist es eine oder mehr Produkttabellen zu erstellen, die die folgenden Anforderungen erfüllen:

  • Support viele Arten von Produkten (TV, Telefon, PC, ...). Jede Art von Produkt hat einen anderen Satz von Parametern, wie:

    • Telefon hat Farbe, Größe, Gewicht, OS ...

    • PC-CPU hat, HDD, RAM ...

  • Der Satz von Parametern muss dynamisch sein. Sie können einen beliebigen Parameter hinzuzufügen oder zu ändern, die Sie mögen.

Wie kann ich diese Anforderungen ohne eine separate Tabelle für jede Art von Produkt erfüllen?

War es hilfreich?

Lösung

Sie haben zumindest diese fünf Optionen zur Modellierung der Typenhierarchie Sie beschreiben:

  • Single Table Inheritance : eine Tabelle für alle Produkttypen, mit genügend Spalten speichern alle Attribute aller Art. Das bedeutet, viel von Säulen, von denen die meisten auf einer bestimmten Zeile NULL sind.

  • Class Table Inheritance : eine Tabelle für Produkte, speichern Attribute, die für alle Produkt Typen. Dann eine Tabelle pro Produkttyp, Attribute spezifisch für diesen Produkttyp zu speichern.

  • Concrete Table Inheritance : keine Tabelle für gemeinsame Produkte Attribute. Stattdessen eine Tabelle pro Produkttyp, die beiden gemeinsame Produktattribute speichern, und produktspezifische Attribute.

  • Serialized LOB : Eine Tabelle für Produkte, Attribute, die für alle Produkttypen speichern . Eine zusätzliche Spalte speichert ein BLOB von semi-strukturierten Daten in XML, YAML, JSON oder ein anderes Format. Das BLOB können Sie die Attribute spezifisch für jeden Produkttyp speichern. Sie können ausgefallenes Design Patterns verwenden diese, wie Fassaden- und Memento zu beschreiben. Aber unabhängig haben Sie einen Klecks von Attributen, die nicht leicht in SQL abgefragt werden können; Sie müssen die gesamte Blob zurück in die Anwendung holen und dort sortieren.

  • Entity-Attribute-Value : Eine Tabelle für Produkte, und eine Tabelle, die Attribute zu den Reihen schwenkt, anstelle von Spalten. EAV ist kein gültiges Design in Bezug auf das relationale Paradigma, aber viele Leute es trotzdem verwenden. Dies ist die „Eigenschaften Pattern“ von einer anderen Antwort erwähnt. Weitere Fragen mit dem eav Tag auf Stackoverflow für einige der Gefahren.

Ich habe in einer Präsentation mehr darüber geschrieben, Extensible Datenmodellierung .


Weitere Gedanken über EAV: Obwohl viele Menschen EAV zu bevorzugen scheinen, das tue ich nicht. Es scheint, wie die flexibelste Lösung und damit die beste. Allerdings halten die adage TANSTAAFL im Auge behalten. Hier sind einige der Nachteile von EAV:

  • keine Möglichkeit, eine Spalte obligatorisch (äquivalent NOT NULL) zu machen.
  • No way SQL-Datentypen zu verwenden, um Einträge zu überprüfen.
  • keine Möglichkeit, dass Attributnamen, um sicherzustellen, werden konsequent geschrieben.
  • Auf keinen Fall einen Fremdschlüssel auf den Werten von einem bestimmten Attribute zu setzen, z.B. für eine Lookup-Tabelle.
  • Ergebnisse in einem herkömmlichen tabellarischen Layout Fetching ist komplex und teuer, weil Attribute aus mehreren Zeilen müssen Sie bekommt JOIN für jedes Attribut tun.

Der Grad der Flexibilität EAV gibt Sie Opfer in anderen Bereichen erfordern, wahrscheinlich Ihr Code so komplex (oder schlechter) zu machen, als es das ursprüngliche Problem in einer konventionelleren Weise zu lösen gewesen wäre.

Und in den meisten Fällen ist es nicht notwendig, dass Maß an Flexibilität zu haben. In der Frage des OP über Produktart, ist es viel einfacher, eine Tabelle für produktspezifische Attribute pro Produkttyp zu erstellen, so dass Sie einige konsistente Struktur für Einträge des gleichen Produkttypen zumindest durchgesetzt werden.

würde ich EAV nur verwenden, wenn jede Zeile muss möglicherweise einen deutlichen Satz von Attributen zulässig. Wenn Sie eine endliche Menge von Produkttypen haben, ist EAV Overkill. Class Table Inheritance wäre meine erste Wahl sein.


Update 2019: Je mehr ich sehe Menschen JSON als Lösung für die „viele benutzerdefinierte Attribute“ Problem verwenden, desto weniger ich diese Lösung gefällt. Es macht auch komplexe Abfragen, auch wenn spezielle JSON Funktionen mit um sie zu unterstützen. Es braucht viel mehr Speicherplatz JSON Dokumente zu speichern, im Vergleich zu normalen in Zeilen und Spalten zu speichern.

Im Grunde genommen keine dieser Lösungen sind einfach oder effizient in einer relationalen Datenbank. Die ganze Idee „variable Attribute“ zu haben, ist grundsätzlich im Widerspruch zu relationaler Theorie.

Was es kommt darauf an, dass Sie eine der Lösungen zur Auswahl, auf deren Basis ist die am wenigsten schlecht für Ihre App. Daher müssen Sie wissen, wie Sie die Daten abfragen gehen, bevor Sie ein Datenbank-Design wählen. Es gibt keine Möglichkeit, eine Lösung zu wählen, die „beste“, weil jede der Lösungen ist vielleicht am besten für eine bestimmte Anwendung sein.

Andere Tipps

@StoneHeart

würde ich mich hier mit EAV und MVC den ganzen Weg.

@ Bill Karvin

  

Hier sind einige der Nachteile   EAV:

No way to make a column mandatory (equivalent of NOT NULL).
No way to use SQL data types to validate entries.
No way to ensure that attribute names are spelled consistently.
No way to put a foreign key on the values of any given attribute, e.g.
     

für eine Lookup-Tabelle.

All diese Dinge, die Sie hier erwähnt haben:

  • Datenvalidierung
  • Attributnamen buchstabieren Validierung
  • obligatorische Spalten / Felder
  • die Zerstörung von abhängigen Attributen Handhabung

meiner Meinung nach gehören nicht in einer Datenbank, weil keiner von Datenbanken sind in der Lage, diese Interaktionen und Anforderungen an ein angemessenes Niveau als Programmiersprache einer Anwendung der Handhabung der Fall ist.

In meiner Meinung nach einer Datenbank auf diese Weise verwendet, ist wie ein Stein mit einem Nagel einschlägt. Sie können es mit einem Felsen tun, sind aber nicht Sie vermuten, einen Hammer zu verwenden, die präziser ist und speziell für diese Art von Aktivität entwickelt?

  

Fetching Ergebnisse in einem herkömmlichen tabellarischen Layout ist komplex und   teuer, weil zu bekommen Attribute   aus mehreren Zeilen müssen Sie trete   für jedes Attribut.

Dieses Problem kann, indem einige Abfragen auf Teildaten gelöst werden und sie in tabellarisches Layout mit Ihrer Anwendung zu verarbeiten. Auch wenn Sie 600GB Produktdaten haben, können Sie es in Chargen verarbeiten, wenn Sie Daten von jeder einzelnen Zeile in dieser Tabelle erforderlich ist.

Weiter zu gehen Wenn Sie die Leistung der Abfragen verbessern möchten Sie bestimmte Operationen wie zum Beispiel wählen können Berichterstattung oder globale Textsuche und die Vorbereitungen für diese Indextabellen, welche Daten benötigt würde speichern und periodisch regeneriert werden würde, alle 30 Minuten können sagen.

Sie brauchen nicht einmal mit den Kosten von zusätzlichen Datenspeicher betroffen, weil es jeden Tag billiger und billiger wird.

Wenn Sie immer noch mit der Leistung des von der Anwendung durchgeführt betroffen sein würde, Sie immer Erlang verwenden kann, C ++, Go Sprache die Daten vorverarbeitet und später verarbeitet nur die optimierten Daten weiter in der Haupt App.

Wenn ich Class Table Inheritance Bedeutung:

  

eine Tabelle für Produkte, Attribute, die für alle Produkttypen zu speichern. Dann eine Tabelle pro Produkttyp, Speicherattribute spezifisch für diesen Produkttyp.   -Bill Karwin

Welche Ich mag das Beste von Bill Karwin die Vorschläge .. Ich kann Art voraussehen ein Nachteil, den ich versuchen zu erklären, wie nicht zu einem Problem zu halten.

Welche Notfallplan sollte ich an der richtigen Stelle, wenn ein Attribut, das nur gemeinsam 1-Typ ist, dann gemeinsam wird auf 2, dann 3, etc?

Zum Beispiel: (dies ist nur ein Beispiel, nicht mein wirkliches Problem)

Wenn wir Möbel verkaufen, könnten wir verkaufen Stühle, Lampen, Sofas, Fernseher, etc. Das TV-Typ könnte die einzige Art sein, die wir führen, dass ein Stromverbrauch hat. So würde ich das power_consumption Attribut auf dem tv_type_table setzen. Aber dann beginnen wir Heimkinosysteme zu tragen, die auch eine power_consumption Eigenschaft. OK es ist nur ein anderes Produkt so werde ich dieses Feld auf die stereo_type_table als auch hinzufügen, da diese zu diesem Zeitpunkt wahrscheinlich am einfachsten ist. Aber im Laufe der Zeit, da wir immer mehr Elektronik zu tragen beginnen, erkennen wir, dass power_consumption breit genug ist, dass es in der main_product_table sein sollte. Was soll ich jetzt tun?

Fügen Sie das Feld auf die main_product_table. Schreiben Sie ein Skript eine Schleife durch die Elektronik und setzen Sie den richtigen Wert von jedem type_table zum main_product_table. Dann fallen die Spalte von jedem type_table.

Wenn ich nun immer war die gleiche GetProductData-Klasse mit der Datenbank zu interagieren, die Produktinformationen zu ziehen; dann, wenn Änderungen im Code jetzt Refactoring benötigen, sollten sie an, dass die Klasse nur sein.

Sie können eine Produkt Tisch haben und eine separate ProductAdditionInfo Tabelle mit 3 Spalten: Produkt-ID, zusätzliche Informationen Name, zusätzlicher Info-Wert. Wenn Farbe, die durch viele, aber nicht alle Arten von Produkten verwendet wird, könnten Sie haben es eine Nullable-Spalte in der Product-Tabelle sein, oder legen Sie sie einfach in ProductAdditionalInfo.

Dieser Ansatz ist nicht eine traditionelle Technik für eine relationale Datenbank, aber ich habe es gesehen viel in der Praxis eingesetzt. Es kann flexibel sein und gute Leistung.

Steve Yegge nennt diese der Mustereigenschaften und schrieb einen langen Pfosten über ihn verwenden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top