0

Okay, also mache ich gerade einen Tisch für "Box Items".Widersprüchliche Wünsche im Datenbank Design, mit Feldern von zwei ähnlichen Funktionen

Nun kann ein Box Item, abhängig davon, was es für den/den Status des Items verwendet, am Ende mit einem "Versand" oder einem "Retouren" Feld in Verbindung gebracht werden.

Ein Box Item ist möglicherweise defekt: Wenn dies der Fall ist, wird in der Zeile des Box Items (IsDefective) ein Flag gesetzt und das Box Item wird in ein "Returns" Feld gesetzt dieser Verkäufer). Andernfalls wird das Box Item eventuell in eine "Versand" Box (mit anderen zu versendenden Artikeln) gelegt. (Beachten Sie, dass die Versand- und Rückgabeboxen ihre eigenen Tabellen haben: es gibt nicht eine gemeinsame Tabelle für alle Boxen ... aber vielleicht sollte ich das als dritte Möglichkeit in Betracht ziehen?)

Vielleicht denke ich einfach nicht klar heute, aber ich begann zu fragen, was in dieser Situation getan werden sollte.

Mein Bauch sagt mir, dass ich ein eigenes Feld für jede mögliche Beziehung haben sollte, selbst wenn nur eine der Beziehungen kann zu einem bestimmten Zeitpunkt geschehen, die das Schema für Box Artikel machen würden wie folgt aussehen:

BoxItemID Beschreibung IsDefective ShippingBoxID ReturnBoxID etc ...

Dies würde die Beziehungen deutlich machen, aber es scheint verschwenderisch (da nur eine der Beziehungen wird jederzeit verwendet werden). Also dachte ich, ich nur ein Feld für die BoxID haben könnte, und bestimmen, welche BoxID es mit Bezug auf (eine Lieferung oder eine Rückgabe Box ID) basierend auf dem IsDefective Feld:

BoxItemID Beschreibung IsDefective BoxID usw. ..

Dies scheint weniger verschwenderisch, aber sitzt nicht richtig mit mir. Die Beziehung ist nicht offensichtlich.

Also, ich habe es Ihnen, Datenbank-Gurus von Stackoverflow. Was würdest du in dieser Situation tun?

EDIT: Vielen Dank für Ihre Eingabe! Es gibt mir viel zu denken. Zum einen werde ich nächstes Mal ein ORM verwenden, wenn ich ein solches Projekt starte. =) Für zwei, da ich gerade nicht bin, beiße ich die vier Bytes und benutze zwei Felder.

Vielen Dank nochmal!

Antwort

2

Ich bin mit Psychotic Venom und Mattlant.

Die polymorphe Route zu gehen (herauszufinden, auf welcher Tabelle Ihr Fremdschlüssel basierend auf dem Inhalt eines anderen Feldes zeigt) wird ein Schmerz sein. Codieren Sie die Einschränkungen für das möglicherweise schwierig (ich bin nicht sicher, dass die meisten Datenbanken das nativ unterstützen würden, ich denke, dass Sie einen Auslöser verwenden müssten).

Bewegen sich Elemente zwischen den Tabellen? Es kann der einfachste Weg sein, mit zwei Tabellen mit identischen Definitionen zu bleiben, wobei eine für die Retoure und eine für den Versand bestimmt ist. Wenn Sie bei der Definition bleiben wollen, die Sie zuerst vorgeschlagen haben (mit den zwei getrennten Feldern), ist das völlig in Ordnung.

"Vorzeitige Optimierung ist die Wurzel allen Übels" und all dies. Während es verschwenderisch scheint, erinnere dich daran, was du speicherst. Da sie IDs sind, sind sie wahrscheinlich nur ganze Zahlen, vielleicht 4 Bytes. Das Verwerfen von vier Bytes pro Datensatz ist im Grunde nichts. In der Tat, aufgrund der Auffüllung, Dinge auf gerade Adressen oder andere solche Dinge zu setzen, kann es "frei" sein, dieses zusätzliche Feld dort hineinzulegen. Es kommt auf das DB-Design an.

Es sei denn, Sie haben einen sehr guten Grund, die polymorphe Route zu gehen (wie auf einem Embedded-System mit wenig Speicher oder Sie replizieren über eine wirklich langsame 9600bps-Verbindung) wird es wahrscheinlich nicht die Kopfschmerzen wert sein kann enden mit. All diese speziellen Fälle in Ihre Abfragen schreiben zu müssen, kann ärgerlich werden.

Kurzes Beispiel: eine Verbindung zwischen zwei Tabellen zu machen, wo, wenn Sie beitreten möchten basiert auf, wenn die IsDefektive Flag gesetzt ist, wird ein Schmerz sein. Die Möglichkeit, nur eine der beiden Spalten zu verwenden, ist wahrscheinlich genug Aufwand, die Sie sparen können, zumindest für mich.

+0

Aye ... Ich denke du hast Recht damit. Ich kann definitiv sehen, was die anderen Jungs davon halten, wenn ich ein ORM hätte ... und ich muss * wirklich * anfangen, eins zu benutzen. =) Aber für den Moment ist alles Handarbeit ... und das scheint für diese Aufgabe besser geeignet zu sein. – EdgarVerona

1

Worüber Sie sprechen sind polymorphe Beziehungen. Eine einzelne ID, die mehrere andere Tabellen referenzieren kann. Es gibt mehrere Frameworks, die dies unterstützen, es ist jedoch (möglicherweise) schlecht für die Datenbankintegrität (das könnte eine ganze andere Diskussion darüber sein, ob Ihre Datenbank oder Ihre Anwendung referenzielle Integrität beibehalten soll oder nicht).

Was ist damit?

BoxItem: 
BoxItemID, Description, IsDefective 

Box: 
BoxID, Description 

BoxItemMap: 
BoxID, BoxItemID, BoxItemType 

Dann können Sie haben BoxItemType eine Aufzählung sein, oder eine ganze Zahl in dem Sie Konstanten in Ihrer Anwendung als „Return“ oder „Versand“ als Art der Box definieren.

1

Ich würde in Betracht ziehen, eine einzige Tabelle für die Boxen und die Box-Typ eine Spalte der Box-Tabelle sein. Dies würde die Beziehungen vereinfachen und die Suche nach Box-Typen erleichtern. Der Box-Eintrag hat also nur einen Fremdschlüssel zur Box-ID.

0

Einigen Sie sich über die polymorphe Diskussion oben, obwohl es Potenzial hat, schlecht verwendet zu werden, ist es immer noch eine praktikable Lösung.

Grundsätzlich haben Sie eine Basistabelle namens Box. Dann haben Sie zwei weitere Tische, Versandkarton und Rückgabekasten. Diese beiden fügen zusätzliche Felder hinzu, die für sie besonders sind. Sie beziehen sich auf Box mit einer 1: 1 fk.Boz Basis-Tabelle hat die gemeinsamen Felder aller Box-Typen.

Sie beziehen BoxItem mit der Box-Tabelle. Die Art und Weise, wie Sie den richtigen Boxentyp erhalten, besteht darin, eine Abfrage auszuführen, die die untergeordnete Box mit der auf dem Schlüssel basierenden Root-Box verbindet. Der Datensatz, der sowohl in der Basis-Box als auch in der untergeordneten Box vorhanden ist, ist von diesem Typ.

Sie müssen nur vorsichtig sein wie erwähnt, dass, wenn Sie eine Box erstellen, dass es richtig gemacht wird. Aber das ist was Testen ist. Der Code, um sie hinzuzufügen, muss nur einmal geschrieben werden. Oder benutze ein ORM.

Fast alle ORMs unterstützen diese Strategie.

0

ich wahrscheinlich mit gehen würde:

BoxTable: 
box_id, box_descrip, box_status_id ... 
    1, Lovely Box, 1 
    2, Borked box, 2 
    3, Ugly Box, 3 
    4, Flammable Box, 4 

     BoxStatus: 
     box_status_id, box_status_name, box_type_id, .... 
        1,Shippable, 1 
        2,Return, 2 
        3,Ugly, 2 
        4,Dangerous,3 

       BoxType: 
       box_type_id, box_type_name, ... 
          1, Shipping box, ... 
          2, Return box, .... 
          3, Hazmat box, ... 

auf diese Weise die Box-Status definiert die Box-Typ, und es ist flexibel, wenn Sie später in ein paar Statusebenen oder Box-Typen auf erweitern müssen.

0

Ich würde mit nur einer BoxItems-Tabelle mit IsDefective, ShippingBoxID, den Versandfeld-bezogenen Feldern, ReturnBoxID und den Rückgabe-Box-verwandten Feldern gehen. Einige Felder sind für jeden Datensatz immer NULL.

Dies ist ein sehr einfaches und selbstverständliches Design, das der nächste Entwickler wahrscheinlich nicht verwirrt. In der Theorie ist dieses Design wegen der garantierten leeren Felder für jede Reihe ineffizient.In der Praxis neigen Datenbanken dazu, eine minimale erforderliche Speichergröße für jede Zeile zu haben, so dass (sofern die Anzahl der Felder nicht groß ist) dieses Design sowieso so effizient wie möglich ist und viel einfacher zu codieren ist.

1

Ich würde verwenden, was Hibernate ruft Table-per-subclass, so dass meine DB mit 3 Tabellen für Boxen aufzuwickeln würde: Box, ShippingBox und ReturnBox. Der FK in BoxItem würde auf Box zeigen.

+0

+1, um Dinge schön objektorientiert zu halten, aber in praktischer Hinsicht denke ich, dass ich es vorziehen würde, ShippingBox und ReturnBox zu einem einzigen Tisch zu kombinieren und damit die dritte "Super-Class" -Tabelle abzuschaffen. –