Ob separate Tabellen für verschiedene Produkttypen erstellt werden sollen oder nicht?

25

Ich bin gerade dabei, eine Datenbank zu entwerfen, und habe Bedenken hinsichtlich meiner anfänglichen Entwurfsentscheidungen ...

Die Produkttypen sind wie folgt: Modelle, Teile, Ersatzteilsätze und Optionen.

Option A (erster Entwurf): Ich plante, separate Tabellen für die oben genannten Produkttypen zu haben. Ich würde sagen, dass 75% der Felder in jeder Tabelle gleich sind.

Ich habe jeden Produkttyp als separate Tabellen erstellt, da ich zwischen ihnen Verknüpfungen erstellen muss. Zum Beispiel kann ein Modell viele Optionen haben und eine Option kann viele Modelle haben. Eine Option kann auch viele Teile haben und ein Teil kann viele Optionen haben ... und so weiter ...

Option B: Anstatt separate Tabellen zu haben, könnte ich eine Tabelle mit dem Namen Product erstellen, die Modell-, Teil-, Ersatzteil-Kits und Optionen umfasst. Ich könnte ein Feld mit dem Namen Typ haben, um zwischen Modell, Optionen usw. zu unterscheiden. Ich nehme an, dass mehrere Felder für bestimmte Produkttypen niemals verwendet werden (Null). Ich vermute, dass hier "nicht die besten Praktiken" ins Spiel kommen würden.

Option B würde die Komplexität des Datenbankentwurfs erheblich verringern. Ich würde mir auch keine Sorgen machen müssen, wenn ich Daten für Abfragen aus einer Reihe von Tabellen abrufen würde ...

bezahlend
quelle
2
An dieser Stelle schlage ich vor, dass Sie Tabellenkalkulationen erstellen, die Ihr Tabellenlayout nachahmen und sie mit Daten füllen. Dadurch werden eventuelle Schwächen aufgedeckt.
Michael Riley - AKA Gunny
Wie werden Sie Fremdschlüssel auf verschiedene Produkte verweisen, wenn sie sich in verschiedenen Tabellen befinden? Lesen Sie bitte die Tabellenvererbung nach.
Neil McGuigan

Antworten:

8

Wenn dies meine Entwurfsentscheidung wäre, würde ich wahrscheinlich eher eine "Option C" wählen (modifizierte Option a).

Zunächst, warum nicht 'Option B':

Zum einen mag ich die Klarheit, dass jedes Produkt einen eigenen Tisch bietet. Wenn es sich nur um eine große Tabelle mit einem Feld zur Bestimmung des Typs handelt, ist die Beziehung nicht so klar.

Zum anderen würde die Indizierungsstrategie immer die Auflistung dieses Typfelds erfordern. Da es sich nur um 4 Typen handelt, ist die Index-Kardinalität extrem niedrig ( SELECT * FROM product_table WHERE type='X'führt im Grunde genommen trotzdem einen vollständigen Tabellenscan durch).

Option C

  • Erstellen Sie eine übergeordnete Tabelle, die nur die Spalten enthält, die alle Typen gemeinsam nutzen
  • Erstellen Sie jeden Produkttyp als eigene Tabelle mit ihren einzelnen Spalten, mit einem zusätzlichen: einem Link zur übergeordneten Tabelle
  • Erstellen Sie jede Verknüpfungstabelle: Product_Option, Model_option usw. mit Verknüpfungen zu den entsprechenden Schlüsseln.
  • Für diejenigen mit wechselseitigen Verknüpfungen (MODEL_OPTION, OPTION_MODEL) gehen Sie vor und erstellen Sie auch diese Tabellen. Dies erhöht die Übersichtlichkeit Ihrer Verknüpfungen für alle, die sie anzeigen.

Der Nachteil besteht in der Komplexität, sicherzustellen, dass Waisen vermieden werden, wenn Dinge aktualisiert / gelöscht werden, und zunächst die Abfragen zu entwerfen, die diese Tabellen verwenden.

Derek Downey
quelle
5
Es gibt jetzt nur 4 Typen, aber was ist, wenn später weitere hinzugefügt werden? Ich bin mir sicher, dass die Hauptprodukttabelle von Amazon ursprünglich "Bücher" hieß, aber glauben Sie, dass sie jetzt für jeden Produkttyp eine separate Tabelle hat? Ich denke nicht, dass jeder Typ eine eigene Tabelle haben sollte, aber Sie könnten ein EAV-Modell für zusätzliche Eigenschaften verwenden, die jeder Typ gemeinsam haben könnte.
Aaron Bertrand
1
@ Aaron Fair Point über die zukünftige Zunahme von Produkttypen. Wenn dieses Szenario möglicherweise auf mehr als 10 Produkttypen ausgeweitet werden könnte, würde ich es mir noch einmal überlegen. Ich bin jedoch der Meinung, dass bestimmte Produkttabellen für eine kleine Anzahl von Produkttypen eine faire Designauswahl darstellen.
Derek Downey
1
Option C: Ist eine Verknüpfungstabelle erforderlich? Ich würde mir vorstellen, dass die Product_Option-PK mit der PK der Product-Tabelle übereinstimmt und dadurch die Verknüpfung beider Tabellen erstellt wird.
Payling
Am Beispiel von Product_option wäre das Schema (meiner Meinung nach): id, productID, optionID. productIDwäre ein FK zu product.id, und optionIDist ein FK zu option.id. Das habe ich mit Verknüpfungstabelle gemeint. Und ja, bei diesem Design ist es erforderlich, dass ein einzelnes Produkt mit mehreren Optionen verknüpft werden kann.
Derek Downey
OK ich verstehe. Ich habe falsch verstanden, was Sie eingegeben haben.
Payling
7

Ich würde vorschlagen, dass Sie mit dem "richtigen" relationalen Modell beginnen, Ihrer Option A. Wenn die typische Verwendung dieses Modells Sie in einigen Bereichen zur Denormalisierung führt, haben Sie keine Angst davor.

Ich habe letzte Woche mit einem Kollegen diskutiert, wie Schemaentwürfe oft als etwas angesehen werden, das in Stein gemeißelt ist und sich nie ändern kann. Seltsamerweise wird das Refactoring eines Datenbankschemas in Anbetracht der Tatsache, dass Refactoring in jeder anderen Ebene einer Anwendung gängige Praxis ist, immer noch als unpraktisch angesehen.

Wenn die Schnittstelle zur Datenbank gut gestaltet ist, hindert Sie nichts daran, das Schema anzupassen, während Sie mehr über die Nutzungsmuster des Systems erfahren.

Mark Storey-Smith
quelle
2

Dies hört sich sehr ähnlich an wie die Erbschaft von Stücklisten / multiplen Kardinalitäten , die Paul Neilsen in Kapitel 17 der SQL Server 2008-Bibel beschreibt .

Das gesamte Kapitel ist sehr gut gelesen und der spezifische Abschnitt, der sich mit Ihrem Many-to-Many-Problem befasst, befindet sich auf den Seiten 416-419.

Dies ist die beste Diskussion, die ich in Bezug auf den Explosionsteiletyp des Datenentwurfs gesehen habe.

Michael Riley - AKA Gunny
quelle
Diese Lösung ähnelt Option B (wenn ich sie richtig verstehe, bin ich mir nicht sicher). Ich hätte eine Master-Tabelle (Produkte) und eine "Link" -Tabelle (auch bekannt als benachbarte Tabelle / Stücklisten), um die Assoziationen zwischen Modellen, Optionen, Kits usw. herzustellen. Ist das richtig?
Payling
Ich denke, das Problem ist aufgrund von Optionen getrübt. Nehmen wir die Optionen ein wenig aus der Diskussion heraus. Teile sind die kleinste Einheit. Eine Gruppe von Teilen bildet ein Modell. Eine Gruppe von Ersatzteilen in Form eines Kits bildet eine Teilmenge des Modells. So weit, ist es gut. Jetzt haben Teile Optionen. Nehmen wir der Einfachheit halber an, dass dies zwei Kategorien umfasst: Farbe (Schwarz, Rot, Chrom) und Material (Metall, Holz, Kunststoff). Sie haben auch erwähnt, dass Modelle Optionen haben. Trennen sich die Modelloptionen von den Teileoptionen, oder scheinen die Modelle nur Optionen zu haben, weil die Teile die Modelle unterschiedlich machen?
Michael Riley - AKA Gunny
Teile haben in meinem Design keine "Optionen". Ich definiere Option als etwas, das auf ein Modell passt, das es mit erweiterter Funktionalität ausstattet. Eine Option besteht aus Teilen. Ein Modell kann viele verschiedene Optionen haben. Eine Option kann auch auf viele verschiedene Modelle passen.
Payling
So haben Sie Ihre Frage nicht formuliert. Zitat: "Zum Beispiel kann ein Modell viele Optionen haben und eine Option kann viele Modelle haben. Eine Option kann auch viele Teile haben und ein Teil kann viele Optionen haben ... und so weiter ..." An dieser Stelle schlage ich Ihnen vor Erstellen Sie Tabellenkalkulationen, die Ihr Tabellenlayout nachahmen, und füllen Sie sie mit Daten. Dadurch werden eventuelle Schwächen aufgedeckt.
Michael Riley - AKA Gunny
0

Wenn Sie sich ein wahrscheinliches Szenario vorstellen können, in dem häufig Fragen zu allen vier Produkttypen auftreten (und das scheint mir wahrscheinlich zu sein), ist Ihre Option B die beste.

Anstatt viele nicht verwendete nullfähige Felder in der Product-Tabelle zu belassen, können Sie eine ModelProduct-Tabelle, eine PartProduct-Tabelle, eine ReplacementPartKitProduct-Tabelle und nur die Felder hinzufügen, die für diese Typen in diesen Tabellen unterschiedlich sind. Verwenden Sie für diese Tabellen denselben Primärschlüssel wie für Ihre Produkttabelle. Verknüpfen Sie die Tabelle Product und ModelProduct, wenn Sie mit Models arbeiten möchten. Müssen Sie feststellen, ob es sich bei Ihrem Produktdatensatz um ein Teil handelt? Führen Sie einfach eine Verknüpfung von Product zu PartProduct durch, und wenn PartProduct. [PrimaryKey] nicht null ist, haben Sie ein Part. Wenn es null ist, ist es kein Teil. Alternativ können Sie der Product-Tabelle ein ProductType-Feld hinzufügen.

Alan McBee
quelle
Die Nullfelder wären minimal, da ungefähr 75% der Felder in jeder Tabelle verwendet würden. Ich denke, ich mache mir mehr Sorgen um die Beziehungen zwischen den Produkttypen. Ich werde drei oder mehr Verknüpfungstabellen haben, die auf dieselbe Tabelle verweisen. Model_has_Option zwei Primärschlüssel, beide Produkt-IDs der Produkttabelle, wenn ich nur eine Tabelle zur Darstellung der Produkttypen verwenden würde. Ich bin eher besorgt, ob das das Richtige ist oder nicht.
Zahlen
Während es viele Faktoren gibt, die die "richtige" Entscheidung beeinflussen, sind zwei allgemeine Faktoren zu berücksichtigen. 1: allgemeine Leistungsanforderungen; 2: Anpassungsfähigkeit / Komplexität / Wartbarkeit. Einer dieser beiden ist wahrscheinlich ein bisschen wichtiger als der andere. Wenn Sie Geschwindigkeit benötigen, denormalisieren Sie, indem Sie sich an Option A halten. das ist zu erwarten. Wenn Sie regelmäßig mit dem Schema experimentieren müssen und Geschwindigkeit nicht der wichtigste Faktor ist, dann wählen Sie Option B. Sie erhalten es "richtig", indem Sie Ihre Prioritäten kennen und sich nicht an die "Best Practices eines anderen" halten.
Alan McBee