Frage zum Entwurf von Datenbanktabellen

7

Erstens Datenbankanfänger hier. Ich versuche, ein System für die Verarbeitung von Kundenaufträgen in Bestellungen zu erstellen und dann die Bestellung in Versandbehälter aufzuteilen. Das System muss in der Lage sein, eine Kundenauftragsposition in zwei oder mehr Bestellungen und eine Bestellposition in zwei oder mehr Versandbehälter aufzuteilen.

Es wird einige (viele) Anpassungen geben, bei denen eine Kundenauftragsposition, sobald sie aufgeteilt und in mehrere Bestellungen aufgeteilt wurde, später möglicherweise anders aufgeteilt wird. Dies gilt auch, wenn eine Bestellposition zu Versandbehältern verarbeitet wird. Ich kann für mein ganzes Leben nicht wissen, wie ich mit dieser Operation am besten umgehen soll.

Wenn es hilft, sind hier die Tabellen, die ich bisher habe, wobei einige Details der Kürze halber ausgeschlossen sind:

CREATE TABLE PurchaseOrder (
    Id INTEGER UNSIGNED UNIQUE NOT NULL AUTO_INCREMENT,
    PurchaseOrderNumber VARCHAR(15) UNIQUE,

    PRIMARY KEY(Id)
);  

CREATE TABLE Container (
    Id INTEGER UNSIGNED UNIQUE NOT NULL AUTO_INCREMENT,
    ContainerName VARCHAR(20) UNIQUE,
    PurchaseOrderId INTEGER UNSIGNED,

    PRIMARY KEY(Id),
    FOREIGN KEY(PurchaseOrderId) REFERENCES PurchaseOrder(Id),
);

CREATE TABLE SalesOrder (
    Id INTEGER UNSIGNED UNIQUE NOT NULL AUTO_INCREMENT,
    ClientId INTEGER UNSIGNED,
    SalesOrderNumber VARCHAR(10),

    PRIMARY KEY(Id),
    FOREIGN KEY(ClientId) REFERENCES Client(Id)
);

CREATE TABLE SalesOrderLineItem (
    Id INTEGER UNSIGNED UNIQUE NOT NULL AUTO_INCREMENT,
    SalesOrderId INTEGER UNSIGNED,
    ProductId INTEGER UNSIGNED,
    Qty INTEGER,
    Price DECIMAL(5,2),
    Cost DECIMAL(5,2),

    PRIMARY KEY(Id),
    FOREIGN KEY(SalesOrderId) REFERENCES SalesOrder(Id),
    FOREIGN KEY(ProductId) REFERENCES Product(Id)
);

CREATE TABLE PurchaseOrderLineItem (
    Id INTEGER UNSIGNED UNIQUE NOT NULL AUTO_INCREMENT,
    PurchaseOrderId INTEGER UNSIGNED,
    SalesOrderId INTEGER UNSIGNED,
    ProductId INTEGER UNSIGNED,
    ClientId INTEGER UNSIGNED,
    MfgId INTEGER UNSIGNED,

    PRIMARY KEY(Id),
    FOREIGN KEY(PurchaseOrderId) REFERENCES PurchaseOrder(Id),
    FOREIGN KEY(SalesOrderId) REFERENCES SalesOrder(Id),
    FOREIGN KEY(ProductId) REFERENCES SalesOrder(Id),
    FOREIGN KEY(ClientId) REFERENCES Client(Id),
    FOREIGN KEY(MfgId) REFERENCES Mfg(Id)
);

Ich denke darüber nach, zusätzliche Zuordnungstabellen zwischen Kundenauftragsposition und Bestellungen sowie für Bestellposition und Container zu erstellen, um diese Art der Aufteilung von Rücken und Schaum zu verfolgen.

Hilfe geschätzt!

User007
quelle
1
Versuchen Sie nur zu prüfen, was passiert ist, oder müssen Sie zeigen, welche Zeilen zu einem bestimmten Zeitpunkt einer bestimmten Bestellung / einem bestimmten Container zugewiesen wurden?
Chris Saxon
1
Sie müssen wissen, welche Zeilen welchen Bestellungen und dann welchen Containern zugeordnet sind. Das Problem ist, dass eine SO-Linie eines Produkts A mit 100 Stück in 2 POs mit jeweils 50 Stück aufgeteilt und dann in 4 Behälter mit jeweils 25 Stück gefüllt werden kann. Um das Problem weiter zu verschärfen, wird dieser Prozess mehrmals auf den ursprünglichen Zustand von 100 Stück zurückgesetzt und dann auf andere Weise auf POs, Container verteilt.
User007
Für eine Kundenauftragsposition sind mindestens vier Versandbehälter erforderlich. Ist das richtig?
Mike Sherrill 'Cat Recall'
Nein, das Minimum ist 1 Container, aber die Anzahl der Container ist eine Variable. Das Problem, das ich momentan nicht lösen kann, ist, dass eine Kundenauftragsposition, sobald sie in x Anzahl von Bestellungen zugeordnet ist, in y Anzahl von Bestellungen geändert werden kann und wird (und sich wahrscheinlich in z Anzahl von Bestellungen ändern wird ...). . Gleiches gilt für eine Bestellposition, wenn diese in x Containern zugeordnet ist. Wir haben einen chaotischen Betrieb, der viel Flexibilität erfordert.
User007

Antworten:

1

Seien Sie im Allgemeinen sparsam mit automatisch generierten Schlüsseln. Wenn Sie einen für den Benutzer benötigen , OK, aber Sie sollten den natürlichen Schlüssel trotzdem erzwingen.

Zum Beispiel haben Sie PurchaseOrder. Es verfügt über einen eindeutigen Schlüssel, der extern bereitgestellt wird. benutze es. Das Hinzufügen eines eigenen automatisch generierten Werts erhöht die Komplexität und nichts anderes.

Ebenso ist SalesOrderLineItem.Id in der gesamten Tabelle eindeutig. Möchten Sie nicht lieber Zeile 1, 2, 3 als 62783444, 62783445, 62783446 sehen? Das macht den Primärschlüssel SaleOrderID, LineItem (anstelle von Id). Gleiches gilt für PurchaseOrderLineItem, das dann den Schlüssel PurchaseOrder LineItem erhält.

Sie erwähnen einige Male "Aufteilen"; Ich nehme an, Sie meinen, eine bestimmte Verkaufsmenge kann auf mehrere Bestellungen und Versandaufträge aufgeteilt werden. Widerstehen Sie der Versuchung (falls es dazu kommt), einen Auslöser zu verwenden, um die Beziehung zu erzwingen, dass beispielsweise die versendete Gesamtsumme nicht höher ist als bestellt. Diese Art von Frage kann in SQL implementiert werden und sollte es sein, jedoch nicht als Einschränkung der referenziellen Integrität. Schreiben Sie eine gespeicherte Prozedur, um zu überprüfen, ob die Bestellung "in Grenzen" ist, und rufen Sie sie zu gegebener Zeit aus Ihrer Anwendung auf. Dies ermöglicht reale anomale Situationen wie verlorene Sendungen und verpfuschte Bestellungen.

Davon abgesehen scheinen Sie für 3NF zu fotografieren, was ein guter Ort ist. Wenn Sie weiterhin die 1: n-Beziehungen befolgen, um Tabellen zu definieren und Einschränkungen konsequent durchzusetzen, erhalten Sie wahrscheinlich ein solides Design.

James K. Lowden
quelle
0
CREATE TABLE PurchaseOrderLineItem (
    Id INTEGER UNSIGNED UNIQUE NOT NULL AUTO_INCREMENT,
    PurchaseOrderId INTEGER UNSIGNED,
    SalesOrderLineItemId INTEGER UNSIGNED,
    SubQty INTEGER UNSIGNED,
    ContainerID INTEGER UNSIGNED,
    ClientId INTEGER UNSIGNED,
    MfgId INTEGER UNSIGNED,

    PRIMARY KEY(Id),
    FOREIGN KEY(PurchaseOrderId) REFERENCES PurchaseOrder(Id),
    FOREIGN KEY(SalesOrderLineItemId) REFERENCES SalesOrderLineItem(Id),
    FOREIGN KEY(ContainerID) REFERENCES Container(Id),
    FOREIGN KEY(ClientId) REFERENCES Client(Id),
    FOREIGN KEY(MfgId) REFERENCES Mfg(Id)
);

Durch die Verknüpfung mit dem SalesOrderLineItem können Sie für jede Kundenauftragsposition mehrere Bestellpositionen in verschiedenen Containern haben.

Die Untermenge kann beispielsweise 25 in vier PurchaseOrderLineItems und die Gesamtmenge von 100 im SalesOrderLineItem sein.

sa555
quelle