轉《商品銷售打折自定義的資料建模》

2021-03-31 15:30:49 字數 4133 閱讀 5296

近期看了idilent的文章《使用物件導向技術解決商品打折問題》,文後有讀者提出要求:如果不同商品的折扣不同怎麼辦? 或者有買一百送五十這種方式,或不同會員等級的折扣不同。 怎麼處理?」idilent認為打折這個問題並不是能夠通過乙個資料庫的字段就可以解決的。有不同的會員,不同的產品,不同的銷售計畫,而這些也是在不停的不變化和增加的。而會員和產品的打折,以及店慶等打折,雖然都是折扣,但是很難抽象成資料庫中的乙個字段或者幾個字段,不使用程式解決,而希望只是通過改變資料庫中的資料,在目前階段實現起來可能還比較困難。

之前我曾參與過乙個影碟出租銷售管理系統的專案開發,負責其中的架構設計和資料建模工作,儘管最後該專案由於某些客觀原因而被放棄,但是該專案中也有打折優惠這方面的功能需求,我也思考過這一塊的資料建模。其實,我們可以把商品銷售打折這樣的商務規則分解成幾個部分,分析各個部分之間的關係,從中找出關鍵點,再將其泛化資料建模,即可實現讓使用者自己定義打折規則。下面開始分析商品銷售打折的商業規則:

一套商品銷售管理資訊系統,必定存在下面兩個實體:顧客,商品,打折這種商業規則一定是圍繞著這兩個實體以及相互間的關係而制定的。回顧我們的購物經歷,打折的需求應該可以分為三種:

1)對特定商品的折扣一般有如下幾種情況:按售價進行一定百分比的打折;原價->**(某個時間段內進行的)的打折;**優惠銷售(如購買某一(幾)種商品後即可按較低的**或折扣購買另一(幾)種商品)。

2)對顧客的的打折方式一般採用會員制,即是按會員等級在交費時直接給與一定的折扣優惠,或者在會員累積消費一定金額後給以一定比例的返點優惠,該方式需要顧客辦理會員卡之類的身份標識卡。

3)對總額的打折方式一般是顧客消費後送出的限定最後使用期限的代金券。

注意到上面三大類折扣方式分解開來,都離不開商品,所以這三種打折方式都是商品的共有屬性,應該歸入到商品表中。另外,一般大型超市多擁有多個分店,而且可能出現各個分店的打折規則略有不同的情況,上面的三種打折規則得同相應的分店一一對應。最後,資料建模大致如下:

店鋪表(shop)

名稱 型別 約束條件 說明

shop_id int 無重複 店鋪標識,主鍵

shop_name varchar(40) 不允許為空 店鋪名稱

shop_addr varchar(80) 不允許為空 店鋪位址

……商品類別表(ware_type)

名稱 型別 約束條件 說明

type_id int 無重複 商品類別標識,主鍵

type_name varchar(20) 不允許為空 商品類別名稱

father int 不允許為空 該類別的父類別標識,如果是頂節點的話設定為某個唯一值

layer char(6) 限定3層,初始值為000000 類別的先序遍歷,主要為減少檢索資料庫的次數

商品表(ware)

名稱 型別 約束條件 說明

ware_id int 無重複 商品標識,主鍵

ware_type int 不允許為空 所屬商品類別,和ware_type.type_id關聯

ware_name varchar(40) 不允許為空 商品名稱

buy_price float 不允許為空 進貨價

sell_price float 不允許為空 銷售價

d_type char(1) 不允許為空 商品打折方式

m_type char(1) 不允許為空 會員打折方式

has_coupon bit 預設值為0 是否有代金券

……說明:

①d_type用來辨別該商品的商品打折方式。"0"表示該商品無商品折扣方式;"1"表示該商品採用百分比打折方式;"2"表示該商品採用**打折方式;"3"表示該商品採用**打折方式,是**打折規則中的必購商品;"4"表示該商品採用**打折方式,是**打折規則中的允購商品。

②m_type用來辨別該商品的會員打折方式。"0"表示該商品不參與會員折扣計算;"1"表示該商品採取會員百分比折扣方式;"2"表示該商品採取會員卡累積消費返點折扣方式。

③has_coupon用來指明該商品是否有代金券。"0"表示該商品無代金券;"1"反之。

商品庫存表(store_table)

名稱 型別 約束條件 說明

store_id int 無重複 庫存標識,主鍵

shop_id int 不允許為空 店鋪標識,和shop.shop_id關聯

ware_id int 不允許為空 商品標識,和ware.ware_id關聯

number int 預設值為0 店鋪庫存數量

unit varchar(10) 不允許為空 銷售單位

商品折扣規則表(discount)

名稱 型別 約束條件 說明

id int 無重複 折扣規則標識,主鍵

s_id int 不允許為空 店鋪標識,和shop.shop_id關聯

w_id int 不允許為空 商品標識,和ware.ware_id關聯

d_value float 不允許為空 打折數值,用來記錄百分比或**

enddate datetime 不允許為空 該規則的終止日期

number int 允許為空 該規則所允許的最大銷量

unit varchar(10) 允許為空 銷售單位

商品**打折表(bind_discount)

名稱 型別 約束條件 說明

b_id int 無重複 **打折規則標識,主鍵

shop_id int 不允許為空 店鋪標識,和shop.shop_id關聯

1st_ware int 不允許為空 必購的商品標識的集合,和ware.ware_id關聯

min_req int 預設值為1 最小必購數量

2nd_ware int 不允許為空 允購的商品標識的集合,和ware.ware_id關聯

max_buy int 預設值為1 最大允購數量

d_type char(1) 不允許為空 打折方式,是百分比方式還是**方式

d_value float 不允許為空 打折數值,用來記錄百分比或**

enddate datetime 不允許為空 該規則的終止日期

number int 允許為空 該規則所允許的最大銷量

unit varchar(10) 允許為空 銷售單位

說明:1st_ware用來記錄必購商品的集合,min_req表示在必購商品集合內的最小購買數量。2nd_ware用來記錄允購商品的集合,max_buy表示達到必購商品的最小購買數量後,所允許購買的允購商品的最大允購數量。舉例說明:某**銷售規定,凡是購買了某系列商品中的任意1件,即可按**購買允購商品中的任意1款1件。這種**方式大家都見過吧?買二送一不過是其中的特例罷了。

會員等級表(member_type)

名稱 型別 約束條件 說明

type_id int 無重複 會員等級標識,主鍵

s_id int 不允許為空 店鋪標識,和shop.shop_id關聯

type_name varchar(10) 不允許為空 會員等級名稱

t_value float 不允許為空 打折百分比或累積消費返點數

condition float 不允許為空 達到該等級所需累積的消費額

會員表(member)

名稱 型別 約束條件 說明

m_id int 無重複 會員標識,主鍵

m_name varchar(10) 不允許為空 會員姓名

type_id int 不允許為空 會員等級標識,和member_type.type_id關聯

score float 預設值為0 會員累積的消費積分

……代金券表(coupon)

名稱 型別 約束條件 說明

c_id int 無重複 代金券標識,主鍵

c_name varchra(20) 不允許為空 代金券姓名

c_value float 不允許為空 代金數額

condition float 不允許為空 所需現金消費

enddate datetime 不允許為空 代金券的終止日期

當然,由於本人所認知的打折方式並不全面,也沒有和相關的業務人士深入討論過這方面的問題。所以,上面的資料建模並不能保證覆蓋現實商品銷售中的的所有打折方式。不過,我相信,採用上面的資料建模來定義打折規則,覆蓋率還是在90%以上的。根據95/5規則,只要給我足夠的時間,再加上專業人士的協助,不計開發成本的話,100%的覆蓋率是可以達到的^-^

最後,由於每張購物清單都是由商品組成,而每種商品的折扣的計算規則並不一定完全相同,所以我認為在用物件導向的設計方法,設計計算折扣的元件時,採用裝飾(decorator)模式比較適合。

商品銷售打折自定義的資料建模

近期看了idilent的文章 使用物件導向技術解決商品打折問題 文後有讀者提出要求 如果不同商品的折扣不同怎麼辦?或者有買一百送五十這種方式,或不同會員等級的折扣不同。怎麼處理?idilent認為打折這個問題並不是能夠通過乙個的字段就可以解決的。有不同的會員,不同的產品,不同的銷售計畫,而這些也是在...

七 建立自定義的HTML Helper 轉

作者翻譯自官方的教程 這篇文章我們來討論一下如何建立我們自己的html helper 以便在mvc檢視中使用。使用html helper可以減少書寫那些煩人的html標記。在這篇文章的第一部分,我們來談一下asp.net mvc框架中現有的html helper,然後我們再來研究兩種建立自定義htm...

自定義UISlider的樣式和滑塊 轉

又做完乙個專案,遂到了寫帖時間了,要跟大家分享的是 自定義uislider的和滑塊,先看一下效果 然後是實現了,我們使用的是uislider的setminimumtrackimage,和setmaximumtrackimage方法來定義 的,這兩個方法可以設定滑塊左邊和右邊的的,不過如果用的是同一張...