引言:資料庫設計
Step by Step (5)——理解使用者需求中我們通過多種方法來理解客戶的需求並撰寫了需求文檔。本文我們將回答三個問題。1. 為什麼商務規則非常重要。2. 怎樣識別商務規則。3. 如何修改關聯式模式並隔離出商務規則。
什麼是商務規則
商務規則描述了業務過程中重要的且值得記錄的對象、關係和活動。其中包括業務操作中的流程、規範與策略。商務規則保證了業務能滿足其目標和義務。
生活中的一些商務規則可能是:
- 當顧客進入店內,最近的員工須向顧客打招呼說:“歡迎來到×××”。
- 當客戶兌換超過200元的獎券時,櫃員須要求查看客戶的身份證並複印。當兌換的獎券金額小於25元時,無需客戶簽字。
- 早上第一個進辦公室的人需要把飲水機加熱按鈕開啟。
本系列我們關注資料庫相關的商務規則,一些例子如下:
- 只有當客戶產生第一個訂單時才建立該客戶的記錄。
- 若一名學生沒有選任何一門課程,把他的狀態欄位設為Inactive。
- 若銷售人員在一個月中賣出10套沙發,獎勵500元。
- 一個連絡人必須至少有1個電話號碼和1個email郵箱。
- 若一個訂單的除稅總額超過1000元則能有5%的折扣。
- 若一個訂單的除稅總額超過500元則免運費。
- 員工購買本公司商品能有5%的折扣。
- 若倉庫中某貨品的存量低於上月賣出的總量時,則需要進貨。
從資料庫的視角來看,商務規則是一種約束。簡單的約束如:
所有訂單必須有一個聯絡電話。
上述這類簡單的規則可以很容易的映射到關聯式資料庫定義中,為欄位確定資料類型或設定某欄位為必填(不能為NULL)。某些商務規則表達的約束會複雜些,如:
學生每天的上課時間加上項目時間必須在1至14小時之間。
我們可以通過check約束或外鍵約束來實現這類商務規則。對於一些非常複雜的商務規則,如:
一名教員每周不能少於30小時工作量,其中分為辦公時間、實驗時間和上課時間。每1小時的課需要0.5小時辦公時間進行備課。每1小時實驗需1小時辦公準備。每周指導學生論文時間不少於2小時。
類似上述的商務規則需要從多個表中收集資料,故在程式碼中實現最為合適。
識別關鍵商務規則
記錄所有的商務規則並對這些規則進行分類能協助我們更好的在系統中實現商務邏輯。
如何?商務規則不僅與當前的商務邏輯有關,而且與該商務邏輯將來如何變化有關。當一個規則在將來很可能變化時,我們需要使用更複雜但更靈活的方式構建該規則。
舉例來說,假設公司只能向當地設有倉庫的城市發貨,這些城市包括:南京、長沙、西安、廣州。商務規則要求訂單中的發貨城市欄位必須為NJ、CS、XA、GZ之一。
我們可以把該規則簡單的實現為check約束。但將來公司若在上海有了一個新倉庫,就必須從後台資料庫端修改該check約束。若公司隨後設立更多新倉庫或商務規則變化為可以向沒有倉庫的城市發貨,每次我們都需要修改該約束。
考慮另一種實現該商務規則的方法——使用外鍵。我們建立一張ShippingCities表,其中存放值:NJ、CS、XA、GZ,並讓訂單表中的發貨城市欄位外鍵引用ShippingCities表中的主鍵。這樣訂單的發貨城市列只能接受ShippingCities中存在的城市。當支援的發貨城市增加或減少時,只需要在ShippingCities中插入或刪除記錄。
兩種方式的實現難度差異不大,但前一種方式每次都需要修改資料庫結構,後一種只需要修改資料。修改資料不僅更省力而且技術要求也更低。
上述商務規則實現為check約束可能如下:
ShippingCity = ‘NJ’ or ShippingCity = ‘CS’ or ShippingCity = ‘XA’ or ShippingCity = ‘GZ’
上述代碼並不複雜,但只有熟悉資料庫的程式員從後台才能修改。ShippingCitis表中的資料相對更易於理解,我們可以提供一個介面來讓使用者自己維護其中的城市。
要識別關鍵商務規則,我們可以問自己兩個問題。
第一、修改規則會有多困難。越是複雜的規則,修改起來越困難且更容易出錯。
第二、規則變化的可能性有多大。變化頻繁的規則需要額外的設計來更好的應對將來的變化。
需要特別注意的規則(關鍵商務規則):
- 枚舉值。例如:有效發貨城市,訂單狀態(Pending, Approved, Shipped)等。
- 計算參數。例如:對500元以上的訂單免運費。這一數值可能在將來會調整為300元或600元。
- 有效參數。例如:項目組可由2至5人組成。某些項目是否可能由1個人完成或有更多人蔘與。
- 交叉記錄和交叉表檢查。例如:訂單中可訂購的貨品數量不能超過該貨品的當前庫存數。
- 可概括性約束。如果可預見到將來需應用一些類似的約束,我們可以考慮把這些約束抽象出來進行管理。例如:某保險公司最近主推保險產品A。對每月能賣出20份A產品的銷售人員給予1000元獎金。對於不同的保險產品在不同的時間段可能有不同的推廣獎勵規則。我們可以把產品名稱、編號、銷售量、獎金數額、促銷時間段提取出來放到一張獨立的表中作為計算獎金的參數。
- 非常複雜的檢查。有些檢查規則非常複雜,把這些規則放到程式碼中實現更為容易和清晰。例如:學生選擇理學院的謂詞演算課程的前提是已通過理學院的命題演算課程或已通過社科院的邏輯I和II課程或者需要導師的允許。該規則在某些資料庫產品中可以通過表級的check約束實現,但放到程式中更易於維護和理解。
一些直接可以在資料庫中實現的商務規則:
- 固定枚舉值。例如:性別(男、女),用手習慣(左撇子、右撇子)。
- 資料類型要求。每個欄位具有確定的資料類型是關係型資料庫的重要特性之一。濫用通用的資料類型(如string)對效能和資料防錯都會帶來損害。
- 必填值。例如:會員必須有手機連絡方式。
- 合理性檢查。合理性檢查設定的範圍基本不會變化。例如:商品的價格大於等於0。
作為軟體從業人員不要拒絕或迴避變化。世界上唯一不變的就是變化。在收集商務規則時多去瞭解該規則的業務背景與曆史變化曆程,而不是逼迫客戶保證規則不會變化。儘可能發現所有的商務規則並記錄下來。對這些商務規則按變化的可能性和修改難度進行分類,精心設計那些將來可能變化且修改困難的規則。
提取關鍵商務規則
識別並分類商務規則之後,我們需要在資料庫中或資料庫外來實現關鍵商務規則。我們可以參考如下方法:
1. 若規則為檢驗一組有效值時,把該規則轉化為外鍵約束。先前舉例中的有效發貨城市就是一個很好的例子。建立ShippingCities表,填入允許的發貨城市。然後把Orders表的ShippingCity列設為外鍵,引用ShippingCities表的主鍵。
2. 若規則為參數可能變化的計算式時,把這些參數提取到一張表中。例如:一個月內賣出總價超過100萬元汽車的銷售人員能獲得500元獎金。把參數100萬元和500元提取到一張表中,如果需要甚至可以把一個月的時間段也作為參數提取出來。
我還見過一些軟體系統在資料庫中有一張通用的參數表。該通用參數表中存放系統需要的各種參數,一些是用於計算、一些是作為檢驗、另一些決定系統的行為。每一條記錄有兩個欄位:Name和Value。例如需要確定一名銷售人員能獲得多少獎金,我們先要尋找Name欄位為BonusSales的記錄,檢查該銷售人員的銷售額是否達到了Value欄位的金額,若答案是肯定的再尋找Name欄位為BonusAward的記錄來確定獎金數額。這種設計另有一好處,在程式啟動時可以把通用參數表讀入記憶體的某集合中,此後使用參數值時就無需再次串連資料庫。
3. 若邏輯或計算規則很複雜時,則提取到代碼中進行實現。這裡說的代碼可以是應用程式端代碼,還可以是資料庫端預存程序。把規則放到代碼中實現的意義在於商務規則與資料庫表結構分離了,規則的變化不會影響到資料庫表結構。通過結構化編程或物件導向編程來實現複雜的規則更易於維護。
舉一個綜合性的例子:
一本關於資料庫設計的書籍賣出前5000本的版稅為5%,5000本至10000本之間的版稅為7%,超過10000本後的版稅為10%,不同類型書籍的版稅可能不同。
上述規則比較複雜且包含多個可能變化的參數,故使用第1、2條方法。我們可以通過預存程序來實現該規則,並把參數隔離到一張參數表中進行維護。建立的參數表為RoyaltyRates,並通過BookId與Books關聯(1所示)。這樣為不同書籍建立新的版稅規則就非常容易了。
圖1
參數表RoyaltyRates與Books表的關係
多層應用的概念大家都不會陌生。三層應用是最常見的分層方法。對於複雜的商務邏輯一般會在中介層(即業務層)中實現。對於一些基本的驗證,如必填資訊、數字有效區間等,需要在最上層使用者介面以及最底層資料庫端進行雙重檢驗。資料庫端的約束是阻隔髒資料進入系統的最後一道防線,而使用者介面處的檢驗可以避免錯誤資料轉送到系統後端才被拒絕,節省了系統資源。
註:關於多層應用的更多資料請參見最後的“總結與參考”部分。
主要內容回顧
1. 商務規則決定了業務如何運行,其涵蓋從簡單明了的入門打卡到複雜的獎金計算公式。
2. 對於資料庫而言,商務規則將影響到資料模型。商務規則確定了每個欄位的域(值的類型和範圍),是否是必須的,以及該欄位要滿足的其他條件。
3. 理解商務規則並識別那些需要特別處理的關鍵規則至關重要。
4. 有些規則簡單且基本不變,它們可以很容易的用資料庫特性來實現。其他的一些規則可能複雜或時常變化,我們可以把它們從資料庫中邏輯的或物理的隔離出來(隔離到參數表、預存程序或業務層中),使它們易於修改。
多層應用參考
1. 談談對於企業級系統架構的理解(http://www.cnblogs.com/liping13599168/archive/2011/05/11/2043127.html)
2. Multitier architecture(http://en.wikipedia.org/wiki/Multitier_architecture)
3. Software Architecture, Architects and Architecting(http://www.bredemeyer.com/)
原文:http://www.cnblogs.com/DBFocus/archive/2011/06/08/2075795.html