舒適提示mysql
週末菜菜送的書,你領了嗎?沒領的話,關注公衆號以後參加活動哦!web
菜菜哥,我又讓領導罵了sql
來,哥安慰一下你,說說你捱罵的緣由,讓哥樂一樂數據庫
....是這樣的,我作的商城有一個訂單統計的功能,我除了記錄訂單以外,還記錄了下單人的信息,其中有省市區縣id的信息架構
傾聽中.......app
而後業務部門會有根據區域(省市區縣)訂單的各類統計需求,好比xx省的訂單數,訂單總金額等統計。less
傾聽中...編輯器
因爲人員的區域信息可能會變更,用戶區域信息就算是同步或者不一樣步都會出現差錯sqlserver
每一個用戶信息只存在一條記錄?flex
是的。好比用戶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(0) from 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妹子的場景倒是真實環境中遇到的問題。問題的本質仍是變性業務和非變性業務的定義和劃分,和架構設計同樣,數據庫的設計其實也須要把變更的業務存儲點進行抽象,其實應該說是抽離出來。
但願你們有所收穫 --菜菜
互聯網之路,菜菜與君一同成長
長按識別二維碼關注