2011-11-01 84 views
4

假設我有兩件「我可以賣的東西」:serviceproduct。每個表格都有一個表格,表示它們的獨特屬性(例如,服務可能有每小時費率,而產品可能有每單位價格等)。針對電子商務的數據庫設計問題

每次進行銷售時,都假設我需要捕獲與銷售完全相同的數據,而不管服務或產品是否已售出。我如何建模?

方法1:

  1. 我創建一個表來保存每個銷售的細節
  2. 我創建兩個「映射」表的產品或服務與銷售表
連接

所以,像這樣:

TABLE: product 
- product_id (PK) 

TABLE: service 
- service_id (PK) 

TABLE: sale 
- sale_id (PK) 

TABLE: product_sale 
- product_id (FK) 
- sale_id (FK) 

TABLE: service_sale 
- service_id (FK) 
- sale_id (FK) 

方法2:

跳過映射表,只是有單獨的表來記錄產品和服務的銷售情況。

TABLE: product 
- product_id (PK) 

TABLE: service 
- service_id (PK) 

TABLE: product_sale 
- product_sale_id (PK) 
- product_id (FK) 

TABLE: service_sale 
- service_sale_id (PK) 
- service_id (FK) 

我覺得方法1會更好,因爲我需要生成像報告:

  • 在一定時期內
  • 每個銷售人員的銷售總額
  • 總銷售額

回答

7

由於您列出的原因,您的方法1比方法2更有利。能夠收集所有類型的銷售數據並在一次銷售中擁有多個物品。方法2表明,產品和服務一次只銷售一次,不捆綁在一起。但是我不得不想知道,爲什麼要首先將產品和服務分開? (根據您的需求,這將是特定行業)。大多數電子商務系統和小型企業會計系統使用一個簡單的模型和一個產品表。

因此,這裏是我用一個產品表你的問題的官方回答是:

  1. 結構中的[產品]表有PricePerUnit和UnitOfMeasure (可能是小時,可能是每個,可能是,對於標準服務可能是預訂率 )。這可以充分描述大多數小公司的產品/服務之間的模型差異定價 。
  2. 現在在您的[product_sale]表(又名「InvoiceLineItem」,以我的 爲例)中添加備註字段。在這個領域,你可以寫出 有關銷售產品/服務的細節。如果是服務, 您可能會輸入一些註釋供客戶參考,如 「執行X服務,調整B部件和拋光C調整 旋鈕」。

所以,你必須在這個簡單的例子三個表:

  • [產品] - 包含主數據或你的產品和服務,包括他們的定價措施,一些單位「目錄」。
  • [發票] - 包含您的銷售信息或發票標題包​​括日期,事務ID,也許銷售人員等
  • [invoicelineitems] - 在許多一對多風格的產品有兩個外鍵連接的發票。

這是多麼現成的電子商務系統和小型企業會計系統的工作原理。

如果您需要超級特定跟蹤,那麼您肯定會變得更加複雜,但您需要通過解釋爲什麼單位架構的價格不適用於您的用例來證明成本和複雜性。 (汽車經銷商就是一個例子,在這個例子中,服務的跟蹤與完全不同,服務/產品在單獨的表格中都與代表關於汽車的「問題」或「投訴」的訂單項相關聯。每個訂單項都有一個產品組件和一個服務組件。)

更新:看起來我在原始答案中不夠清楚,正如@Doug指出的那樣。創建銷售發票時,當需要轉換交易時,將當前PricePerUnit複製到InvoiceLineItem記錄以及QuantitySold字段以及對產品主數據的快照非常重要的任何其他數據。這確保發票始終保持相同的總額,即使未來產品價格發生變化。如果客戶退貨,並且確保客戶獲得與付款相同的金額,無論當前價格如何,它還允許您撤銷發票。

0

我已經做到了以上這樣一次:

表產品: - PRODUCT_ID(PK) - 描述 - product_type_id(FK)

表發票:

  • invoice_id
  • client_id

表invoice_line: - INVOICE_ID - PRODUCT_ID - product_type_id - 價格

表PRODUCT_TYPE - product_type_id - 描述

所以,在你的最後一個表,設置兩個itens:1 - 「產品」, 2 - 「服務」 產品將按照「1」,「香蕉」,「1」(這是一種產品)創建。 服務將像這樣創建「2」,「換油」,「2」(這是一項服務);

現在,在創建發票時,請確保將所選產品的product_type_id傳遞到invoice_line表中。這樣可以在查詢「SELECT * from invoce_line WHERE product_type_id = 2」等數據時獲得更高的性能 - 獲取銷售服務的所有數據。 (1個產品)。

因此,您將所有發票數據都保存在唯一表格中;你可以得到的,例如,所有的客戶通過一個簡單的服務連接查詢像(CLIENT_ID是10):

Select * from invoice_line 
join invoice 
on invoice_line.invoice_id = invoice.invoice_id and client_id = 10 
where product_type_id = 2 

這會做的伎倆幾乎一切。我有超過1000人在這樣的事情上工作,直到今天,沒有任何缺陷。

希望它有幫助。

0

如果您試圖規範化數據庫,第一種方法是有利的。在這種情況下,對於不同的產品,您可以使用sale實體的屬性與sale_id = xx。在第二種情況下,如果您銷售的是每個銷售的多個產品/服務(銷售交易),則需要複製銷售的屬性。

按人物/日期範圍查詢可以使用索引策略/分區來解決。如果你知道你的數據會快速增長......所以這將是關於DW項目的另一個問題。

希望它有幫助。

5

事實上,我會做不同的看法:

TABLE: salable 
- salable_id (PK) 
- price (per unit) 
- unit ("hour", "kilogram", "part", "unit") 
- description 

TABLE: product 
- salable_id (FK) 
- manufacturer 
- units_in_stock 

TABLE: service 
- salable_id (FK) 
- provider 

TABLE: sale 
- sale_id (PK) 
- salable_id (FK) 
- units 
- total 

點在於「實用」摘要的東西是共同的服務和產品。這可能不是您的理想解決方案,但它是其他人尚未提及的可行設計。

附錄:爲確保準確的記錄,大多數受尊重的銷售/財務系統會爲每個銷售的每個訂單項記錄每個產品/服務記錄的快照。由於我們應該拍賣我們的產品記錄快照無論如何,更容易和更直接的方法是所有可出售的商品共享一組核心領域。

+0

謝謝@svidgen。我其實只是考慮了抽象,而不是實際的影響。 –

+0

我喜歡你的方法,但我會將salable_id,單位和總數從銷售移至sale_datails。此外,我會在sales_detail上重複價格,因爲價格可能會發生變化,所以每個人都這樣做。 – danihp

1

方法1最適合您的目的。它也適用於構建在數據庫層之上的中間件層 - 您可以輕鬆地將ORM解決方案放在現有數據庫結構上,並使用第一種方法建模

0

在編寫本文時,我相信,答案是忽略一個東西:

當東西的價格變化時會發生什麼?

我提起這件事是因爲你特別提到了報道。

以前的所有銷售是否都顯示新價格?是否所有的服務費用都以相同的費率(或者一些客戶可以享受折扣?)

我認爲您的「銷售」的域名概念需要包含純粹爲價值對象的「已售商品」。

這可能不重要 - 但你必須決定這樣的事情。這就是爲什麼領域模型得到很多揮手的原因。

所以我建議選擇1,但考慮到產品/服務銷售表應該指的是sold_product和sold_service,而不是「原產地」產品/服務。