假設你是一家百貨公司電腦部的開發人員,某天老闆要求你爲公司開發一套網上電子商務平臺,該百貨公司有數千種商品出售,不過目前僅打算先在網上銷售數十種方便運輸的商品,當然,以後可能會陸續在該電子商務平臺上增加新的商品出售。現在開始進行該平臺數據庫的商品信息表的設計。每種出售的商品都會有相同的屬性,如商品編號,商品名稱,商品所屬類別,相關信息,供貨廠商,內含件數,庫存,進貨價,銷售價,優惠價。你很快就設計出4個表:商品類型表(Wares_type),供貨廠商表(Wares_provider),商品信息表(Wares_info):
商品類型表(Wares_type)
名稱 類型 約束條件 說明
type_id int 無重複 類別標識,主鍵
type_name char(50) 不允許爲空 類型名稱,不允許重複
type_father int 不允許爲空 該類別的父類別標識,如果是頂節點的話設定爲某個唯一值
type_layer char(6) 限定3層,初始值爲000000 類別的先序遍歷,主要爲減少檢索數據庫的次數
供貨廠商表(Wares_provider)
名稱 類型 約束條件 說明
provider_id int 無重複 供貨商標識,主鍵
provider_name char(100) 不允許爲空 供貨商名稱
商品信息表(Wares_info)
名稱 類型 約束條件 說明
wares_id int 無重複 商品標識,主鍵
wares_name char(100) 不允許爲空 商品名稱
wares_type int 不允許爲空 商品類型標識,和Wares_type.type_id關聯
wares_info char(200) 允許爲空 相關信息
provider int 不允許爲空 供貨廠商標識,和Wares_provider.provider_id關聯
setnum int 初始值爲1 內含件數,默認爲1
stock int 初始值爲0 庫存,默認爲0
buy_price money 不允許爲空 進貨價
sell_price money 不允許爲空 銷售價
discount money 不允許爲空 優惠價
你拿着這3個表給老闆檢查,老闆希望能夠再添加一個商品圖片的字段,不過只有一部分商品有圖片。OK,你在商品信息表(Wares_info)中增加了一個haspic的BOOL型字段,然後再建了一個新表——商品圖片表(Wares_pic):
商品圖片表(Wares_pic)
名稱 類型 約束條件 說明
pic_id int 無重複 商品圖片標識,主鍵
wares_id int 不允許爲空 所屬商品標識,和Wares_info.wares_id關聯
pic_address char(200) 不允許爲空 圖片存放路徑
程序開發完成後,完全滿足老闆目前的要求,於是正式啓用。一段時間後,老闆打算在這套平臺上推出新的商品銷售,其中,某類商品全部都需添加“長度”的屬性。第一輪折騰來了……當然,你按照添加商品圖片表的老方法,在商品信息表(Wares_info)中增加了一個haslength的BOOL型字段,又建了一個新表——商品長度表(Wares_length):
商品長度表(Wares_length)
名稱 類型 約束條件 說明
length_id int 無重複 商品圖片標識,主鍵
wares_id int 不允許爲空 所屬商品標識,和Wares_info.wares_id關聯
length char(20) 不允許爲空 商品長度說明
剛剛改完沒多久,老闆又打算上一批新的商品,這次某類商品全部需要添加“寬度”的屬性。你咬了咬牙,又照方抓藥,添加了商品寬度表(Wares_width)。又過了一段時間,老闆新上的商品中有一些需要添加“高度”的屬性,你是不是開始覺得你所設計的數據庫按照這種方式增長下去,很快就能變成一個迷宮呢?那麼,有沒有什麼辦法遏制這種不可預見性,但卻類似重複的數據庫膨脹呢?我在閱讀《敏捷軟件開發:原則、模式與實踐》中發現作者舉過類似的例子:7.3 “Copy”程序。其中,我非常贊同敏捷軟件開發這個觀點:在最初幾乎不進行預先設計,但是一旦需求發生變化,此時作爲一名追求卓越的程序員,應該從頭審查整個架構設計,在此次修改中設計出能夠滿足日後類似修改的系統架構。下面是我在需要添加“長度”的屬性時所提供的修改方案:
去掉商品信息表(Wares_info)中的haspic字段,添加商品額外屬性表(Wares_ex_property)和商品額外信息表(Wares_ex_info)2個表來完成添加新屬性的功能。
商品額外屬性表(Wares_ex_property)
名稱 類型 約束條件 說明
ex_pid int 無重複 商品額外屬性標識,主鍵
p_name char(20) 不允許爲空 額外屬性名稱
商品額外信息表(Wares_ex_info)
名稱 類型 約束條件 說明
ex_iid int 無重複 商品額外信息標識,主鍵
wares_id int 不允許爲空 所屬商品標識,和Wares_info.wares_id關聯
property_id int 不允許爲空 商品額外屬性標識,和Wares_ex_property.ex_pid關聯
property_value char(200) 不允許爲空 商品額外屬性值
在商品額外屬性表(Wares_ex_property)中添加2條記錄:
ex_pid p_name
1 商品圖片
2 商品長度
再在整個電子商務平臺的後臺管理功能中追加一項商品額外屬性管理的功能,以後添加新的商品時出現新的屬性,只需利用該功能往商品額外屬性表(Wares_ex_property)中添加一條記錄即可。不要害怕變化,被第一顆子彈擊中並不是壞事,壞的是被相同軌道飛來的第二顆、第三顆子彈擊中。第一顆子彈來得越早,所受的傷越重,之後的抵抗力也越強8)