程序員過關斬將--你的業務是可變的嗎(福利你領了嗎)


溫馨提示

周末菜菜送的書,你領了嗎?沒領的話,關注公眾號之后參加活動哦!

菜菜哥,我又讓領導罵了

來,哥安慰一下你,說說你挨罵的原因,讓哥樂一樂

....是這樣的,我做的商城有一個訂單統計的功能,我除了記錄訂單之外,還記錄了下單人的信息,其中有省市區縣id的信息

傾聽中.......

然后業務部門會有根據區域(省市區縣)訂單的各種統計需求,比如xx省的訂單數,訂單總金額等統計。

傾聽中...

由於人員的區域信息可能會變動,用戶區域信息就算是同步或者不同步都會出現差錯

每個用戶信息只存在一條記錄?

是的。比如用戶A現在屬於省id為1000的省,生成了一個訂單,這個省的訂單數統計會加1,假如訂單總數變為了20001,然后用戶A所屬的省的Id變為了1001,那Id是1000的省的訂單總數又變成了20000

我明白你的問題了,來,妹子,哥給你好好說說這個事

請不要跟我說用ES或者其他,其實很多中小公司的業務就是如此,就是基於mysql或者sqlserver 來搞這樣的業務

業務場景


        不知道通過D妹子的闡述,大家了解情況了沒。這里菜菜再詳細說一下。D妹子的程序記錄了訂單的log來供其他業務(比如統計)使用,這里就以統計業務來說,OrderLog表設計如下:


列名 數據類型 描述
OrderId nvarchar(100) 訂單號,主鍵
UserId int 下單用戶id
Amount int 訂單的金額
其他字段省略...


除此之外還有一個用戶信息表UserInfo,設計如下:

列名 數據類型 描述
UserId int 用戶id,主鍵
ProvinceId int 用戶省的id
CityId int 用戶市的id
CountyId int 用戶區縣的id

涉及到拆單等復雜的訂單操作,表的設計可能並非如此,但是不影響菜菜要說的事

變數的業務


現在假如要統計某個省的訂單總數,sql如下:


select count(0from OrderLog o inner join UserInfo u on o.UserId=u.UserId where ProvinceId=@ProvinceId


        有問題嗎,sql沒問題,這時候用戶A的省市區縣信息突然變了(也許是在其他地區買房,戶口遷移了),也就是說UserInfo表里的信息變了,那用以上的sql統計用戶A以前省市區縣的訂單信息是不是就會出錯了呢?(產品狗說在哪下的訂單就屬於哪的訂單)

業務的定位


        以上的問題你覺得是不是很簡單呢?只要稍微修改一下表也許就夠了。但是,菜菜要說的不是針對這一個業務場景,而是所有的業務場景的設計。那你有沒有想過為什么D妹子的設計會出現這樣的問題呢?

        深刻理解業務才能避免以上類似的錯誤發生,一定要深刻理解不變和可變的業務點。 拿D妹子的統計來說,你的業務是統計區域的訂單數,這個業務在產品設計上定義的是不變性,也就是說在行為產生的那個時間點就確定了業務性質,這個業務的性質不會隨着其他變而變。具體到當前業務就是:用戶在X省下的訂單不會隨着用戶區域信息的變化而變化,說白了就是說用戶在X省生成的訂單永遠屬於X省。

        談到業務性質的不變性,對應的就有業務的可變性。假如你開發過類似於QQ空間這樣的業務,那肯定也做過類似訪客的功能。當要顯示訪客記錄的時候,訪客的名稱在多數情況的設計中屬於可變性的業務。什么意思呢?也就是說一個用戶修改了姓名,那所有顯示這個用戶訪問記錄的的地方姓名都會同時改變。

        說到這里,各位再回頭看一下D妹子的業務,這里又牽扯到一個系統設計的問題,眾所周知,一個好的系統設計需要把業務的變化點抽象提取出來,D妹子訂單統計的業務變化點在於用戶的省市區縣會變化,訂單的金額、訂單號等信息不會變化。所以你們覺得是不是D妹子的數據表可以修改一下呢?


數據表的改進

01

改進用戶信息

按照以上的闡述,D妹子業務的變化點在於用戶的省市區域信息,所以可以把用戶信息的表抽象提取出來,主鍵不再是用戶id


列名 數據類型 描述
Id int 主鍵Id,主鍵
UserId int 用戶id
ProvinceId int 用戶省的id
CityId int 用戶市的id
CountyId int 用戶區縣的id


這樣的話用戶訂單log表中就變為

列名 數據類型 描述
OrderId nvarchar(100) 訂單號,主鍵
UserBId int 對應用戶表中的主鍵id
Amount int 訂單的金額
其他字段省略...


這樣設計的話,如果用戶的省市區縣信息有變動,相應的用戶信息表中會存在多條用戶省市區縣數據

這里的用戶信息表並非是用戶對象的主表,而是根據訂單業務衍生出來的表

02

改進業務數據表

根據業務的變性和不變性,既然把訂單區域統計的業務定義為不變的業務性質,那訂單的log表完全可以這樣設計

列名 數據類型 描述
OrderId nvarchar(100) 訂單號,主鍵
UserId int 下單用戶id
ProvinceId int 用戶省的id
CityId int 用戶市的id
CountyId int 用戶區縣的id
Amount int 訂單的金額
其他字段省略...


寫在最后

各位讀到這里,可能會感覺菜菜這次寫的其實很雞肋,但是,D妹子的場景卻是真實環境中遇到的問題。問題的本質還是變性業務和非變性業務的定義和划分,和架構設計一樣,數據庫的設計其實也需要把變動的業務存儲點進行抽象,其實應該說是抽離出來。


希望大家有所收獲 --菜菜

互聯網之路,菜菜與君一同成長

長按識別二維碼關注

你點的每個推薦,我都認真當成了喜歡


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM