2008-11-13 210 views
66

這不是真正關於「編程」的問題(不是特定於任何語言或數據庫),而是更多的設計和架構。這也是「做X的最佳方式」類型的問題。我希望不會引起太多的「宗教」爭議。庫存數據庫設計

在過去,我開發了一種以某種方式保留某種形式的物品清單(不相關的物品)的系統。有些使用不支持事務的語言/數據庫。在這些情況下,我選擇不將項目數量保存在項目記錄中的字段中。相反數量是根據收到的庫存總量計算的 - 總出售庫存量。由於軟件,這導致庫存幾乎沒有差異。這些表格正確編制索引,性能良好。如果記錄的數量開始影響性能,則存在歸檔過程。

現在,幾年前我開始在這家公司工作,並且我繼承了一個跟蹤庫存的系統。但數量保存在一個領域。當一個條目被註冊時,收到的數量被添加到該條目的數量字段中。銷售商品時,將減去數量。這導致了差異。在我看來,這不是正確的方法,但以前的程序員在這裏發誓。

我想知道在設計這樣的系統時,是否有正確的方法達成共識。還有哪些資源可用,打印或聯機,以便尋求這方面的指導。

感謝

+13

當你說「以前的程序員在這裏發誓」時,你的意思是他們每次需要發誓時都會發誓嗎? – MusiGenesis 2008-11-13 15:50:08

回答

47

我在當前公司看到了兩種方法,並且肯定會傾向於第一種方法(基於股票交易計算總數)。

如果您只是在某個字段中存儲總數量,則不知道如何到達該數字。沒有事務歷史記錄,最終會出現問題。

我寫的最後一個系統通過將每筆交易存儲爲正數量或負數量的記錄來跟蹤股票。我發現它工作得很好。

+1

+1我有同樣的困境,現在我認爲這是最好的選擇 – INS 2010-11-10 20:03:24

+3

@尼爾 - 你可以評論這種方法的性能。它似乎是最受歡迎的方法,但是如果您有數百種產品和數千種交易,您計算累積總計的方式或時間。或者你是否只是在知道可以重新計算需要的情況下將累計總數存儲在另一個地方並且安心? – 2011-07-13 20:01:10

+0

@Simon按理說,它只會比查詢一個字段的性能低得多。我必須說,我從來沒有用大量的產品來描述它。最好嘗試一下,看看你的數據集有什麼樣的性能。然後決定是否值得在某處緩存數量。 – 2011-07-14 15:14:00

3

我會選擇第一種方式,其中

庫存量計算 合計庫存接受 - 總 存貨的出售

正確的方式, IMO。

編輯:我也想將任何股票損失/損害因素納入系統,但我相信你已經涵蓋了這一點。

9

這取決於,庫存系統遠不僅僅是計數物品。例如,出於會計目的,您可能需要根據FIFO(先進先出)模型瞭解庫存的會計值。這不能通過簡單的「收到的總庫存 - 已售庫存總量」公式計算出來。但他們的模型可能很容易計算出來,因爲他們會隨着會計價值的變化而改變。我不想深入細節,因爲這不是編程問題,但如果他們發誓,也許你不能完全理解他們必須滿足的所有要求。

4

重要的是要考慮現有的系統以及改變它的成本和風險。我使用存儲類似於您的庫存的數據庫,但它包含審計週期和存儲調整,就像收據一樣。它似乎運作良好,但所有參與者都訓練有素,而且倉庫人員並不快學習新程序。我想建議添加一個跟蹤表(類似於'事務'解決方案),然後將更改記錄到日誌文件中庫存水平。更新對庫存水平的大部分更改應該不會太難,因此他們也會留下交易記錄。您還可以添加週期性任務以每隔幾個小時左右將庫存水平備份到事務處理表,以便即使您錯過了事務處理,您也可以發現更改何時發生或回滾到以前的狀態。

如果你想看看大型應用程序是如何看待SugarCRM,他們有庫存管理模塊,儘管我不確定它是如何存儲數據的。

1

我可以看到有兩個欄目的好處,但我沒有關注有關差異的部分 - 你似乎暗示有兩列(進出)不易出現差異,而不是單列(當前)。這是爲什麼?

7

兩者都是有效的,這取決於具體情況。前者是最好的,當以下條件成立:

  • 項目總和的數量相對較少
  • 有很少或沒有特殊情況要考慮(返回,調整等)
  • 庫存項目數量上沒有另一方面需要經常

,如果您有大量的項目,一些特殊情況下,頻繁的訪問,這將是更有效地維持項目數量

還要注意,如果你的系統有差異,然後它有缺陷應追蹤並消除

我已經做了系統兩種方式,都可以的方式工作得很好 - 只要你不理睬錯誤!

3

我認爲這實際上是一個普遍的最佳實踐問題,關於每次您需要總計與每次更改時計算相關的數量(相對)昂貴的計數,然後將計數存儲在字段中並讀取該字段每當你需要一個總數。

如果我不能使用的交易,我會與現場計數每次我總需要時間去。如果交易是可用的,它可以安全地進行庫存更新操作,並在同一事務中重新計算總,這將保證計數的準確性的儲蓄(雖然我不知道這將與多個用戶工作擊中數據庫)。

但是,如果性能不是一個真正的大問題(現代數據庫足以用來計算行數,我甚至不會擔心這一點),我只需堅持每次實時計數。

0

是不是有一個或兩列,我的意思與「共收到庫存 - 銷售的總庫存量」是這樣的:

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

然後

Qunatity_on_hand = inventory_received - inventory_sold 

請記住我簡單地說明了這一點以及我最初的解釋。我知道,只有追蹤數量的庫存還有很多,但在這種情況下,問題在於我們想要解決的問題。在這一點上,改變它的原因是精確地支持當前設計引起的問題的成本。

另外我想提一下,雖然這不是一個「編碼」的問題是有關的算法和設計,恕我直言,這是非常重要的話題。

感謝大家爲你的答案迄今。

尼爾森MARMOL

0

我們解決不同的問題,但我們對他們中的一些做法可能是有趣的你。

我們允許系統進行「最佳猜測」,並向用戶提供有關任何看起來錯誤的猜測的定期反饋。

若要將此庫存,你可以有3個字段:

inventory_received 
inventory_sold 
estimated_on_hand 

然後,您可以運行一個進程沿着線(每天):

SELECT * 
FROM Inventory 
WHERE estimated_on_hand != inventory_received - inventory_sold 

當然,這依賴於查看此警報的用戶並對此進行處理。

此外,你可以有一個函數一些如何,無論是通過更新inventory_sold重置庫存/接收,或者增加另一場「inventory_adjustment」,它可以是正的或負的。

...只是有些想法。希望它有幫助。

5

在藝術看看(協會零售技術標準)的數據模型(http://nrf-arts.org)。它使用具有記錄的StockLedger表,每個項目和庫存更改都在InventoryJournalEntries中進行跟蹤。

1

我曾參與過解決此問題的系統。我認爲理想的解決方案是一個預先計算的專欄,它可以讓你兩全其美。你的總數是一個領域的地方,因此沒有昂貴的查找,但它不能與其他數據(數據庫保持完整性)不同步。我不記得哪些RDMS支持預先計算的列,但是如果您沒有交易,那也可能無法提供。

您可能使用觸發器僞造預先計算的列(非常有效......我沒有看到任何缺點)。儘管你可能需要交易。恕我直言,在進行這種控制的非規範化時保持數據完整性是觸發器的唯一合法用途。

1

Django-inventory面向固定資產,但可能會給你一些想法。

IE:ItemTemplate中(類) - > ItemsOnHand(實例)

ItemsOnHand可以鏈接到更多的ItemTemplate;示例打印機&墨盒是必需的。這也允許爲每個ItemOnHand設置Reorder點。

每個ItemsOnHand鏈接到InventoryTransactions,這允許輕鬆審計。 爲了避免計算千日元的實際庫存物品,我們使用的檢查點只是一個餘額+日期。要計算手頭的物品查詢以查找最近的檢查點,並開始添加或減少物品以查找物品的當前餘額。定期定義新的檢查點。