Ich entwickle ein Werkzeug, das (elektrische) Teile handhabt. Die Teile können erstellt, angezeigt, geändert, gelöscht, gruppiert usw. werden.
Um diese Frage für zukünftige Besucher nützlich zu machen, möchte ich diese Frage universell halten, da das Verwalten von Teilen in einer Datenbank sehr häufig ist, unabhängig davon, welche Teile sich in der Datenbank befinden (CDs, Autos, Lebensmittel, Studenten, ...).
Ich denke an 3 verschiedene DB-Designs:
Verwenden einer Teiletabelle und abgeleiteter Tabellen für spezielle Teileattribute.
Parts (id, part_type_id, name) PartTypes (id, name) Wires (id, part_id, lenght, diameter, material) Contacts (id, part_id, description, picture)
Verwenden Sie nur spezielle Teiletabellen.
Wires (id, name, lenght, diameter, material) Contacts (id, name, description, picture)
Verwenden einer Parts-, PartTypes-, ValueTypes- und PartValues-Tabelle, die alle Werte enthält.
PartTypes (id, name) ValueTypes (id, part_type_id, name) Parts (id, part_type_id, name) PartValues (part_id, value_type_id, value)
Welches bevorzugen und warum? Oder gibt es eine bessere?
Ich bin besorgt über die DB-Abfragen. Ich möchte nicht, dass die Abfragen zu langsam oder zu kompliziert werden.
Aktualisieren
Die Anzahl der Typen in der Datenbank ist ziemlich gegeben und statisch, da sie auf einem internationalen Standard beruhen und selten erweitert werden.
quelle
Antworten:
Option 3 : (manchmal)
Option 3 ist das "EAV" -Design. Theoretisch ist es schön, weil die Felder aus der Tabellenstruktur herausgenommen werden und zu Daten werden. Aber es gibt schreckliche Leistung. Es verbietet auch die Verwendung einer ordnungsgemäßen Indizierung. Und es macht Abfragen viel komplizierter.
Ich würde EAV nur unter besonderen Umständen verwenden. Ich habe EAV verwendet, um die für Bestellungen benötigten Hilfsteile zu berechnen, und es hat gut funktioniert. Aber seien Sie sehr müde, es als Design für Ihre Kerntabellen zu verwenden.
Option 2 : (nie?)
Option 2 ist ein Nein Nein. Was ist mit den freigegebenen Feldern? Werden Sie die Tabellenstruktur für jedes gemeinsam genutzte Feld duplizieren? Dazu müssten Sie Gewerkschaften in Berichte des gesamten Systems aufnehmen.
Option 1 : (Gewinner!)
Option 1 mag etwas zu einfach erscheinen, ist aber wahrscheinlich die beste Wahl für Ihre Kerntabellen. Alle Teile verwenden dieselbe Haupttabelle für freigegebene Felder, um Vereinigungen in Ihren Berichten zu vermeiden. Es hat eine großartige Leistung, die die ordnungsgemäße Verwendung der Indizierung ermöglicht. Abfragen sind im traditionellen Stil und einfach.
Der Nachteil von Option 1 ist, dass Sie Felder nicht dynamisch hinzufügen können. Aber willst du das wirklich? Durch dynamisches Hinzufügen von Feldern führen Sie zur Laufzeit ein Datenbankdesign durch.
quelle
Ich würde dazu neigen, Option 3 nicht zu wählen.
Option 3 ist die Einrichtung von Name-Wert-Paaren, die gegen die Normalisierung verstößt.
Im Idealfall wird versucht, ein gewisses Maß an Normalisierung der Datenbank zu erreichen. Streben Sie eine vollständige Normalisierung an und denormalisieren Sie sie nach Bedarf, wenn sie für Anpassungs- oder Leistungsprobleme identifiziert wird.
Betrachten Sie die Abfrage "Wie lauten die Namen und Teile-IDs für alle Drähte aus Kupfer?"
Struktur # 1 ist
Struktur # 2 ist
Struktur # 3 ist
Berücksichtigen Sie auch die Komplikation von Einfügungen und Löschungen aus dem System.
Lesen Sie weiter, warum nicht # 3 - Der Fluch des Name-Wert-Paares
quelle
part_type_id = part_types.id
undvalue_types.id = part_values.type_value_id
sind beide Klauseln beitreten verlassen die wo nach wo ein Teil Typ Draht ist, Werttyp ist Material und Wert ist Kupfer Das ist relativ prägnantIch gehe Option 3
Option 1 ist schlecht, da Sie nicht möchten, dass Ihre Joins auf einem abgelegten Wert basieren. (dh
If type ="Wire" join to TblWire
)Option 2 ist schlecht, da Sie keine Möglichkeit haben, über Ihr gesamtes Inventar zu berichten
quelle
Ich würde mit einem Daten- / Objektmodell beginnen, das die Vererbung zulässt, und dann eine standardmäßige objektrelationale Zuordnung verwenden . Auf diese Weise kann eine Basisklasse erhalten
Parts
und Unterklassen wieWires
,Contacts
usw. Nun, wenn Sie eine „Karte-jede-Klasse-to-own-Tabelle“ Strategie anwenden, erhalten Sie die Option 1, die die meist „normalisierte“ Lösung ist und sollte die kanonische Strategie sein, wenn Sie keine weiteren Informationen zu den von Ihnen erwarteten Abfragen haben.Option 2 erhalten Sie, wenn Sie einen "Map-Each-Concrete-Class-to-Own-Table" -Ansatz anwenden. Dies kann "Verknüpfungen" vermeiden und bei Abfragen (insbesondere bei Abfragen nur für einen "Teiletyp") eine bessere Leistung erzielen. Andererseits wird die generische Behandlung mit allen Teilen schwieriger und langsamer. Vermeiden Sie dies, wenn Sie keine besonderen Gründe dafür haben.
Option 3 ist nur dann erforderlich, wenn der Benutzer die Anzahl der Teiletypen zur Laufzeit ändern soll. Wenn Sie diese Anforderung nicht erwarten, ist Option 3 ein perfektes Beispiel für Überentwicklungen.
quelle
Mit der NOSQL DB-Datenbank (wie zum Beispiel MongoDB) benötigen Sie nur einen Satz mit dem Namen "Parts". Jeder Teil in diesem Satz wird als Dokumentdatensatz mit variablem Feldsatz bezeichnet:
Ich denke, dass dies der natürlichste Datenspeicher für die von Ihnen beschriebene Aufgabe ist.
quelle
Entscheiden Sie sich auf jeden Fall für Option 1, aber mit ein paar sehr einfachen Änderungen:
Sie können dann CHECK-Einschränkungen und DEFAULT-Werte verwenden, um sicherzustellen, dass die part_type_id korrekt ist. Anschließend können Sie sowohl part_type_id als auch part_id verbinden. Dadurch wird vermieden, dass eine bedingte Verknüpfung nur auf einer Tabelle basiert. Wenn Sie Drähten eine part_type_id hinzufügen müssen (sagen wir, wir unterteilen diesen Teil und fügen eine weitere Tabelle mit erweiterten Attributen hinzu), können die Standard- und Überprüfungsbeschränkungen geändert werden.
quelle
wires.id
und entfernen,contacts.id
da die(part_id, part_type_id)
Kombination ausreicht, um ein Teil eindeutig zu identifizieren.Option 3 ist allgemeiner und kann mehr Anwendungsfälle berücksichtigen.
Wenn Sie Option 3 wählen, benötigen Sie möglicherweise mehr Verknüpfungen und komplexe Abfragen für einfache Funktionen. In Option 2 benötigen Sie komplexe Abfragen für "große" Funktionen wie Inventar und Berichte und müssen möglicherweise Gewerkschaften verwenden, um dies zu erreichen.
Sie können Ihre Abfragen in Option 3 mithilfe von Ansichten jederzeit vereinfachen. Wenn Sie häufig nur den Draht oder Kontakt benötigen, erstellen Sie für jede eine Ansicht. Sie können es optimieren, wenn es notwendig wird.
quelle