2011-11-04 147 views
4

說我賣出product。有時,product實際上是其他product的組合。例如,說我賣一個:數據庫設計:產品和產品組合

  • 熱狗
  • 蘇打
  • 熱狗+蘇打組合

我應該如何模擬這樣的事情?我是否應該有一個product表來列出各個產品,然後是描述組合的product_combo表,以及與productproduct_combo相關聯的另一個表以列出組合中的產品?這對我來說似乎很簡單。

但是,如果我想將所有銷售記錄在一張表中,該怎麼辦?意思是,我不想要product_sales表和product_combo_sales表。我希望所有的銷售都在一張桌子上。我有點不確定如何以這種方式對產品和產品組合進行建模,之後我可以將所有銷售記錄在一張表中。

對此提出建議?

注:我想知道是否可以將產品和產品組合放在一張使用父 - 子關係的表中。用一張桌子,然後錄製銷售將不會很難。我只需要實現一個業務規則,即在已經針對該組合編輯了一個產品組合時,編輯實際上會導致一個新條目。雖然可能會變得混亂。

回答

4

這取決於您實際需要如何處理您的系統。需要跟蹤庫存的系統需要了解,「組合餐」需要通過一個熱狗和32盎司蘇打(或其他)來清點庫存。然而,一個只追蹤訂單和美元的系統並不真正在意組合餐會有什麼「進入」 - 只有你賣掉了一個並獲得了報酬。

也就是說,假設您需要庫存系統。您可以通過稍微改變您的定義來降低複雜性。考慮(1)庫存物品和(2)菜單項。您的inventory_items表格包含您購買並追蹤爲庫存的物品(熱狗,蘇打水等)。您的menu_items表格包含您銷售的物品(Big Dog Combo Meal,熱狗(僅限三明治)等)。

你可以有,巧合的是,具有相同的名稱作爲庫存項目,但對於對待他們,你做一個組合項目以同樣的方式,堅持一個記錄插入鏈接表這些菜單項的一些菜單項:

inventory_items   menu_items  recipes (menu_item, inventory, qty) 
---------------   ------------  ---------- 
hot dog     Hot Dog   Hot Dog, hot dog, 1 
hot dog bun    Hamburger  Hot Dog, hot dog bun, 1 
hamburger patty (4oz)  Big Dog Combo Hamburger, hamburger patty (4oz), 1 
hamburger bun    Soda (32oz)  Hamburger, hamburger bun, 1 
cola          Big Dog Combo, hot dog, 1 
ginger ale         Big Dog Combo, hot dog bun, 1 
              Big Dog Combo, *soda, 32 
              Soda (32oz), *soda, 32 

只是構建這個例子,事實證明,即使是低熱狗也有兩個組件(你必須計算髮髻),而不僅僅是一個。爲了提出最簡單的情況(一個單一組件的菜單項),我在菜單中添加了蘇打水。但是,考慮一下,如果你打算清點非食品物品(杯子),那麼即使是一個簡單的蘇打水也會有兩個組件(三個如果你正在清理吸管)。

請注意,使用此設計,將不會有處理組合項目和非組合項目的特殊代碼路徑。所有與菜單相關的功能將只使用menu_items表格,所有庫存和食物準備相關功能將JOINmenu_itemsrecipes和(如果需要額外的字段)到inventory_items

您需要對可選組件(酸菜,津津有味,辣椒等)以及可以從不同庫存項目中選擇的組件(在此模型中表示爲蘇打)進行特殊處理,但這會讓您開始。

+0

嗨拉里,我還在想你的解決方案。我試圖解決的問題實際上並不僅僅是食物。它也可能是其他項目。我試圖分析你的解決方案,看它是否足夠滿足我需要的。 – StackOverflowNewbie

+0

我在做銷售時記錄什麼?我是否存儲對'menu_items'的PK的引用?如果是這樣,那意味着一旦出售該特定物品,我就需要保留該記錄以用於歷史目的。這樣我就知道出售menu_item的「熱狗」實際上意味着熱狗和熱狗包子。如果該menu_item稍後被編輯(例如,意味着熱狗,熱狗包,芥末),那麼該編輯應該實際上導致在menu_item的表中創建新的條目。 – StackOverflowNewbie

+0

或者,我可以在銷售記錄中存儲menu_item的熱狗通過複製'recipes'中的相關記錄來表示的意思。如果熱狗的意思後來改變,那很好。這意味着什麼已經存儲在銷售記錄中。我想我不應該允許一個menu_item的硬銷售一旦出售(再次保存歷史數據);我只是爲它設置一個標誌。思考? – StackOverflowNewbie

0

我建議你根據「訂單」和「項目」來思考。一個訂單由許多項目組成。項目可以是不同的「產品」。因此,對於訂單實例可以是:

1)熱狗

2)蘇打

3)熱狗+蘇打爲物品

例子可以是:

A)熱狗

B)蘇打水

也可以通過這種方式在銷售訂單表中保留銷售。 我不認爲你需要在數據庫中擁有「組合」的價值。 這是應該在代碼中應用的業務邏輯,而不是在數據庫中應用。 您可以稍後在代碼中應用所有折扣。

+0

組合的價格通常比單個產品的總和低。 – StackOverflowNewbie

+1

是的 - 在代碼中定義組合列表,並且如果某個訂單包含組合列表,則對該項目應用定義的折扣。這個邏輯不被放置在數據庫中!想象一下,今天你給5%的折扣,明天你想改變它爲3%...或者你想添加/刪除「組合」... – hovanessyan

0

你們的方法都行。但至少有一種方法可以解決將產品折扣應用於產品組合的問題(這意味着您也可以選擇性地分攤折扣),例如

CREATE TABLE products 
(
    id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, 
    name VARCHAR(128), 
    description TEXT, 
    price INT 
); 
CREATE TABLE combo_discounts 
(
    id NOT NULL PRIMARY KEY AUTO_INCREMENT, 
    name VARCHAR(128), 
    description TEXT 
); 
CREATE TABLE cd_products 
(
    cd_id INT /* REFERENCES combo_discounts.id */, 
    p_id INT /* REFERENCES product.id */ 
    price_reduction INT 
); 
CREATE TABLE sales 
(
    id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, 
    location ...whatever... 
); 
CREATE TABLE sales_items 
(
    sale_id INT /* REFERENCES sales.id */ 
    p_id INT /* REFERENCES product.id */ 
    cd_discount INT /* REFERENCES cd_products.cd_id */ 
); 

但是記住,你需要使用程序代碼分配折扣銷售(和標誌,當您去各賣出項),以解決有人買2個熱狗和一個問題蘇打(因此只獲得一次折扣)。

...,因此總價格銷售是

SELECT SUM(p.price)-SUM(cd.price_reduction) 
FROM sales s INNER JOIN sales_items si ON (si.sale_id=s.id) 
    LEFT JOIN cd_products cdp ON (si.cd_discount = cdp.cd_id 
     AND si.p_id=cdp.p_id) 
AND s.id=?