Inventardatenbankdesign [geschlossen]

77

Dies ist eine Frage, die sich nicht wirklich mit "Programmieren" befasst (ist nicht spezifisch für eine Sprache oder Datenbank), sondern eher mit Design und Architektur. Es ist auch eine Frage vom Typ "Was ist der beste Weg, um X zu machen". Ich hoffe, dass dies nicht zu vielen "religiösen" Kontroversen führt.

In der Vergangenheit habe ich Systeme entwickelt, die auf die eine oder andere Weise eine Art Inventar von Gegenständen führen (nicht relevant, welche Gegenstände). Einige verwenden Sprachen / DBs, die keine Transaktionen unterstützen. In den Fällen , entschied ich mich nicht Element zu speichern Zahl für die in einem Feld in dem Artikeldatensatz. Stattdessen wird die verfügbare Menge als Gesamtbestand berechnet - Gesamtbestand verkauft. Dies hat zu fast keinen Unstimmigkeiten im Inventar aufgrund von Software geführt. Die Tabellen sind ordnungsgemäß indiziert und die Leistung ist gut. Es gibt einen Archivierungsprozess für den Fall, dass die Anzahl der Datensätze die Leistung beeinträchtigt.

Vor einigen Jahren begann ich in dieser Firma zu arbeiten und erbte ein System, das das Inventar verfolgt. Die Menge wird jedoch in einem Feld gespeichert. Wenn ein Eintrag registriert wird, wird die empfangene Menge dem Mengenfeld für den Artikel hinzugefügt. Wenn ein Artikel verkauft wird, wird die Menge abgezogen. Dies hat zu Unstimmigkeiten geführt. Meiner Meinung nach ist dies nicht der richtige Ansatz, aber die vorherigen Programmierer hier schwören darauf.

Ich würde gerne wissen, ob es einen Konsens darüber gibt, wie man ein solches System richtig entwirft. Auch welche Ressourcen verfügbar sind, gedruckt oder online, um sich hierzu beraten zu lassen.

Vielen Dank

nmarmol
quelle
15
Wenn Sie sagen "die vorherigen Programmierer hier schwören darauf", meinen Sie damit, dass sie jedes Mal schwören, wenn sie daran arbeiten müssen?
MusiGenesis

Antworten:

53

Ich habe beide Ansätze in meinem derzeitigen Unternehmen gesehen und würde mich definitiv dem ersten zuwenden (Berechnung der Gesamtsummen basierend auf Aktiengeschäften).

Wenn Sie nur eine Gesamtmenge in einem Feld irgendwo speichern, haben Sie keine Ahnung, wie Sie zu dieser Nummer gekommen sind. Es gibt keine Transaktionshistorie und es können Probleme auftreten.

Das letzte System, das ich geschrieben habe, verfolgt den Bestand, indem jede Transaktion als Datensatz mit einer positiven oder negativen Menge gespeichert wird. Ich habe festgestellt, dass es sehr gut funktioniert.

Neil Aitken
quelle
1
+1 Ich hatte das gleiche Dilemma und ich denke jetzt, dass dies die beste Wahl ist
INS
4
@Neil - können Sie die Leistung dieses Ansatzes kommentieren? Es scheint der bevorzugte Ansatz zu sein, aber wenn Sie Hunderte von Produkten und Tausende von Transaktionen haben, wie oder wann berechnen Sie die kumulierten Summen. Oder speichern Sie die kumulierte Summe nur an einem anderen Ort, ohne die Gewissheit zu haben, dass Sie sie bei Bedarf neu berechnen können?
Simon_Weaver
11
Ich habe einen Test durchgeführt - ich habe über 3 Produkte ungefähr 3 Millionen Datensätze (von positiven und negativen Bestandsanpassungen) veröffentlicht. Es dauerte nur einen Bruchteil einer Sekunde, um die Gesamtsumme aller nach SKU gruppierten Zeilen zu zählen. Ich muss sagen, ich war absolut erstaunt, wie schnell es funktioniert hat, und für das Projekt, das ich mache, habe ich definitiv noch Wachstum in Größenordnungen und muss mich nicht so schnell darum kümmern. Wenn Sie auf einer Website Echtzeit-Inventarsummen anzeigen, möchten Sie diese wahrscheinlich zwischenspeichern, aber selbst bei allen 2000 Produkten kann ich die Gesamtsummen fast sofort berechnen.
Simon_Weaver
2
Bank- / Buchhaltungssysteme machen etwas Ähnliches mit Transaktionen (Debit oder Credit), oft als separate Felder, aber mit dem gleichen Summierungseffekt. In erster Linie aus betrieblichen Gründen wird ein monatlicher Saldo erstellt (normalerweise gibt es einen Überprüfungsprozess zum Monatsende). Dies ist jedoch auch eine Methode, um 12 monatliche Delta-Zahlen zu addieren, um schnell ein Jahr anstelle jeder Transaktion in einem Jahr zu addieren . Wenn dies über Jahre und Millionen von Konten hinweg erfolgt, ist der Leistungsvorteil real und ermöglicht auch eine Korrektur vor einigen Monaten, sodass nur die Neuberechnung des Monatsabschlusses erforderlich ist.
ClearCrescendo
1
Sie sollten beide anwenden, 1 Feld ist Menge und 1 Tabelle für die Transaktion. Das Mengenfeld kann bei Bedarf neu berechnet werden. Sie benötigen dieses Feld wegen der Leistung. Wenn Ende des Monats. Wir sollten alle Zahlen vor dem Monat in den neuen Monat verschieben. Dies ist mein ERP-System funktioniert. und funktioniert gut
Gray Wolf
9

Es kommt darauf an, dass Inventarsysteme weit mehr sind als nur das Zählen von Artikeln. Für Buchhaltungszwecke müssen Sie möglicherweise den Buchhaltungswert des Inventars basierend auf dem FIFO-Modell (First-in-First-out) kennen. Dies kann nicht mit der einfachen Formel "Gesamtbestand erhalten - Gesamtbestand verkauft" berechnet werden. Ihr Modell kann dies jedoch leicht berechnen, da sie den Buchhaltungswert im Laufe der Zeit ändern. Ich möchte nicht auf Details eingehen, da dies kein Programmierproblem ist, aber wenn sie darauf schwören, haben Sie vielleicht nicht alle Anforderungen verstanden, die sie erfüllen müssen.

lubos hasko
quelle
7

beide sind je nach den Umständen gültig. Ersteres ist am besten, wenn folgende Bedingungen erfüllt sind:

  • Die Anzahl der zu summierenden Elemente ist relativ gering
  • Es sind nur wenige oder keine Ausnahmefälle zu berücksichtigen (Renditen, Anpassungen usw.).
  • Die Menge der Inventargegenstände wird nicht sehr oft benötigt

Wenn Sie dagegen eine große Anzahl von Artikeln, mehrere Ausnahmefälle und häufigen Zugriff haben, ist es effizienter, die Artikelmenge zu verwalten

Beachten Sie auch, dass Ihr System bei Unstimmigkeiten Fehler aufweist, die aufgespürt und beseitigt werden sollten

Ich habe Systeme in beide Richtungen gemacht, und beide Wege können gut funktionieren - solange Sie die Fehler nicht ignorieren!

Steven A. Lowe
quelle
1
hmm. Rendite ist nicht wirklich außergewöhnlich, oder? es sei denn, Sie verkaufen rein verderbliche Gegenstände oder etwas anderes, das nicht
weiterverkauft werden
2
@ Simon: Eines der frühen Inventarsysteme, die ich geschrieben habe, war für eine eigene Eisdiele. Renditen waren nicht nur außergewöhnlich, sie waren praktisch unmöglich ;-)
Steven A. Lowe
5

Schauen Sie sich das Datenmodell ARTS (Association for Retail Technology Standards) an ( http://nrf-arts.org ). Es wird eine StockLedger-Tabelle mit einem Datensatz für jeden Artikel verwendet, und Änderungen am Inventar werden alle in InventoryJournalEntries verfolgt.

Eddie Deyo
quelle
4

Es ist wichtig, das vorhandene System sowie die Kosten und das Risiko einer Änderung zu berücksichtigen. Ich arbeite mit einer Datenbank, in der Inventar ähnlich wie bei Ihnen gespeichert ist, die jedoch Prüfzyklen enthält und Anpassungen genau wie Belege speichert. Es scheint gut zu funktionieren, aber alle Beteiligten sind gut ausgebildet, und die Lagermitarbeiter sind nicht gerade schnell darin, neue Verfahren zu erlernen.

In Ihrem Fall, wenn Sie nach etwas mehr Nachverfolgung suchen, ohne die gesamte Datenbankstruktur zu ändern, würde ich vorschlagen, eine Nachverfolgungstabelle hinzuzufügen (ähnlich wie bei Ihrer Transaktionslösung) und dann Änderungen auf der Inventarebene zu protokollieren. Es sollte nicht zu schwierig sein, die meisten Änderungen an der Inventarebene zu aktualisieren, damit sie auch einen Transaktionsdatensatz hinterlassen. Sie können auch eine periodische Aufgabe hinzufügen, um den Lagerbestand alle paar Stunden in der Transaktionstabelle zu sichern, sodass Sie selbst dann, wenn Sie eine Transaktion verpassen, feststellen können, wann die Änderung stattgefunden hat, oder auf einen vorherigen Status zurücksetzen können.

Wenn Sie sehen möchten, wie eine große Anwendung SugarCRM betrachtet , verfügen sie über ein Bestandsverwaltungsmodul, obwohl ich nicht sicher bin, wie die Daten gespeichert werden.

Eric Goodwin
quelle
4

Ich denke, dies ist eigentlich eine allgemeine Best-Practice-Frage, wie man jedes Mal, wenn Sie eine Summe benötigen, eine (relativ) teure Zählung durchführt, anstatt diese Zählung jedes Mal durchzuführen, wenn sich etwas ändert, die Zählung dann in einem Feld zu speichern und dieses Feld zu lesen, wann immer Sie eine benötigen gesamt.

Wenn ich keine Transaktionen verwenden könnte, würde ich jedes Mal, wenn ich eine Gesamtsumme benötige, die Live-Zählung durchführen. Wenn Transaktionen verfügbar sind, ist es sicher, die Inventaraktualisierungsvorgänge und das Speichern der neu gezählten Summe innerhalb derselben Transaktion durchzuführen, wodurch die Genauigkeit der Zählung sichergestellt wird (obwohl ich nicht sicher bin, ob dies mit mehreren Benutzern funktionieren würde die Datenbank treffen).

Aber wenn die Leistung nicht wirklich ein großes Problem ist (und moderne Datenbanken gut genug sind, um Zeilen zu zählen, über die ich mir selten Sorgen machen würde), würde ich mich jedes Mal an die Live-Zählung halten.

MusiGenesis
quelle
3

Ich würde mich für den ersten Weg entscheiden, wo

Die verfügbare Menge berechnet sich aus dem gesamten erhaltenen Inventar - dem gesamten verkauften Inventar

Der richtige Weg, IMO.

EDIT: Ich würde auch eventuelle Bestandsverluste / -schäden im System berücksichtigen wollen, aber ich bin sicher, dass Sie dies abgedeckt haben.

Galwegisch
quelle
2

Ich habe bereits an Systemen gearbeitet, die dieses Problem lösen. Ich denke, die ideale Lösung ist eine vorberechnete Spalte, mit der Sie das Beste aus beiden Welten erhalten. Ihre Summe wäre irgendwo ein Feld, also keine teuren Suchvorgänge, aber es kann nicht nicht mehr mit dem Rest Ihrer Daten synchronisiert werden (die Datenbank behält die Integrität bei). Ich erinnere mich nicht, welche RDMS vorberechnete Spalten unterstützen, aber wenn Sie keine Transaktionen haben, ist diese möglicherweise auch nicht verfügbar.

Sie könnten möglicherweise vorberechnete Spalten (sehr effektiv ... ich sehe keinen Nachteil) mit Triggern fälschen. Sie würden wahrscheinlich Transaktionen benötigen. Meiner Meinung nach ist die Wahrung der Datenintegrität bei dieser Art der kontrollierten Denormalisierung die einzig legitime Verwendung für einen Trigger.

rmeador
quelle
2

Das Django-Inventar ist eher auf das Anlagevermögen ausgerichtet, kann Ihnen aber einige Ideen geben.

IE: ItemTemplate (Klasse) -> ItemsOnHand (Instanz)

ItemsOnHand kann mit weiteren ItemTemplates verknüpft werden. Beispiel Drucker & Tintenpatronen erforderlich. Auf diese Weise können Sie auch Nachbestellungspunkte für jeden ItemOnHand festlegen.

Jedes ItemsOnHand ist mit InventoryTransactions verknüpft. Dies ermöglicht eine einfache Prüfung. Um zu vermeiden, dass aus Tausenden von Rechnungsgeschäften tatsächlich verfügbare Artikel berechnet werden, werden Prüfpunkte verwendet, die nur einen Saldo + ein Datum darstellen. Um die vorhandenen Elemente zu berechnen, fragen Sie nach dem neuesten Prüfpunkt und beginnen Sie mit dem Hinzufügen oder Entfernen von Elementen, um den aktuellen Artikelbestand zu ermitteln. Definieren Sie regelmäßig neue Prüfpunkte.

Roberto Rosario
quelle
1

Ich kann einige Vorteile für die beiden Spalten sehen, aber ich folge nicht dem Teil über Diskrepanzen - Sie scheinen zu implizieren, dass die beiden Spalten (rein und raus) weniger anfällig für Diskrepanzen sind als eine einzelne Spalte (aktuell). Warum ist das so?

Max Mustermann
quelle
0

Wenn ich nicht eine oder zwei Spalten habe, ist das, was ich mit "Gesamtbestand erhalten - Gesamtbestand verkauft" gemeint habe, ungefähr so:

Select sum(quantity) as inventory_received from Inventory_entry
Select sum(quantity) as inventory_sold from Sales_items

dann

Qunatity_on_hand = inventory_received - inventory_sold

Bitte denken Sie daran, dass ich dies und meine erste Erklärung zu stark vereinfacht habe. Ich weiß, dass es viel mehr zu inventarisieren gibt, als nur die Mengen zu verfolgen, aber in diesem Fall liegt das Problem darin, was wir beheben wollen. Zu diesem Zeitpunkt ist der Grund für die Änderung genau die Kosten für die Unterstützung der Probleme, die durch das aktuelle Design verursacht werden.

Ich wollte auch erwähnen, dass, obwohl dies keine "Codierungs" -Frage ist, sie sich auf Algorithmen und Design bezieht, die meiner Meinung nach sehr wichtige Themen sind.

Vielen Dank an alle für Ihre bisherigen Antworten.

Nelson Marmol

nmarmol
quelle
2
Der Nachteil dieser speziellen Lösung besteht darin, dass die Leistung mit der Zeit immer schlechter wird, da Sie alle jemals erhaltenen oder verkauften Bestände auf unbestimmte Zeit aufzeichnen müssen, um die richtige aktuelle Menge zu erhalten!
Steven A. Lowe
0

Wir lösen verschiedene Probleme, aber unsere Herangehensweise an einige davon könnte für Sie interessant sein.

Wir erlauben dem System, eine "beste Vermutung" anzustellen und den Benutzern regelmäßig Feedback zu diesen Vermutungen zu geben, die falsch aussehen.

Um dies auf das Inventar anzuwenden, können Sie 3 Felder haben:

inventory_received
inventory_sold
estimated_on_hand

Dann könnten Sie einen Prozess (täglich?) Ausführen, der wie folgt aussieht:

SELECT * 
FROM   Inventory
WHERE  estimated_on_hand != inventory_received - inventory_sold

Dies hängt natürlich davon ab, dass Benutzer diese Warnung betrachten und etwas dagegen unternehmen.

Sie können auch eine Funktion zum Zurücksetzen des Inventars haben, indem Sie entweder inventar_sold / empfangen aktualisieren oder ein weiteres Feld "Inventar_Anpassung" hinzufügen, das positiv oder negativ sein kann.

... nur ein paar Gedanken. Hoffe es ist hilfreich.

AJ.
quelle