從一個審批需求看資料庫設計——聯合主鍵的使用
阿新 • • 發佈:2018-12-30
最近工作挺忙,已經接近996了,所以部落格更新也少了。今天忙裡偷閒,分享一個最近遇到的一個數據庫設計問題。業務需求是:
- 針對一條人員資訊的資料進行審批操作
- 在進行審批時要看到審批前後資料的修改
- 同一人員的審批資料只能存在一條
- 審批通過後資料在正式表中生效
- 審批通過後儲存審批結果資料
業務邏輯本身並不複雜,我們可以建一個跟正式表完全相同的臨時表來儲存修改的資料,再增加一個審批結果來標識這條資料。
假如正式表為:
ID(pk) | INFO1 | info2 | … |
---|---|---|---|
00001 | test | test | … |
那麼我們臨時表可以設計為
ID(pk) | info1 | info2 | … | AUDIT_RESULT |
---|---|---|---|---|
00001 | updated | updated | … | pass |
這樣的設計符合直覺,實現起來也很簡單,但問題是這個方法的擴充套件性不夠好。原因是正式表的欄位可能有很多,這些欄位的型別也千差萬別。假如以後加入了新功能需要對正式表的部分欄位進行修改審批,當前的臨時表就不能滿足了。因為臨時表是以id為主鍵的,如果繼續使用臨時表,則之前的審批結果就無法儲存了。為了滿足今後的擴充套件,臨時表需要重新設計。
臨時表的基礎上加一個欄位AUDIT_TYPE ,把AUDIT_TYPE設定為主鍵。表結構如下:
ID(pk) | AUDIT_TYPE(pk) | INFO1 | INFO2 | … | AUDIT_RESULT |
---|---|---|---|---|---|
00001 | 01 | updated | updated | … | pass |
00001 | 02 | updated | updated | … | reject |
設定AUDIT_TYPE以後就可以區分出各種型別的審批,方便針對其他類似的需求進行擴充套件。當然實際使用的時候應該考慮業務的要求,如果業務沒有潛在的擴充套件需求用第一個方法也是可行的。
這個設計思路可以推廣到其他資料庫的設計。每個月備份正式表的資料,我們就可以加一個月份作為聯合主鍵。舉個例子:
ID(pk) | MONTH(pk) | INFO1 | INFO2 | … |
---|---|---|---|---|
00001 | 201801 | test | test | … |
類似的例子還有很多,這裡就不多費口舌了。