亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

數(shù)據(jù)庫模型設計——歷史與版本設計

系統(tǒng) 1943 0

在企業(yè)數(shù)據(jù)庫設計中,經(jīng)常會遇到一個需求,就是希望把操作之前的數(shù)據(jù)保留下來,能夠看到操作之前是什么數(shù)據(jù),操作之后是什么數(shù)據(jù)。對于這種需求,我們可以使用保留歷史數(shù)據(jù)或者使用版本來實現(xiàn)。

為了能夠保留歷史數(shù)據(jù),在版本設計時有以下方案:

?

一、使用版本號

版本號是一種常見的版本設計方案,就是在要進行歷史數(shù)據(jù)保留的表上面增加一個版本號字段,該字段可以是DateTime類型,也可以是int類型,每進行數(shù)據(jù)操作時,都是創(chuàng)建一個新的版本,版本是只增不減的,所以只需要拿到最大一個版本號,就能得到最新的業(yè)務數(shù)據(jù)。

版 本號除了能夠用于留存歷史數(shù)據(jù)外,還有一個功能就是避免并發(fā)編輯操作。比如我們有一個對象A,當前的版本是1,兩個用戶同時打開了該對象的編輯頁面,進行 數(shù)據(jù)更改。先是甲用戶提交更改,這個時候系統(tǒng)把對象的ID和版本進行查詢,發(fā)現(xiàn)要修改的數(shù)據(jù)最新版本是1,所以成功修改,保存了對象A的新版本2。這個時 候用戶乙也提交了修改。系統(tǒng)把對象的ID和版本1進行查詢,發(fā)現(xiàn)要修改的數(shù)據(jù)最新版本是2,不符合要求,所以拒絕用戶乙的修改。用戶乙只有刷新界面,拿到 最新的版本2,再進行修改。

ID 單號 金額 版本號
1 EXP123 100 1

在使用版本號的情況下,對單據(jù)的金額進行修改,修改后創(chuàng)建新的版本號2:

ID 單號 金額 版本號
1 EXP123 100 1
2 EXP123 120 2

二、使用生效、失效時間

保存歷史數(shù)據(jù)的第二辦法是使用生效失效時間來表示一個版本。要進行歷史數(shù)據(jù)記錄的表增加“生效時間”“失效時間”兩個字段,兩個字段不允許為空。對于剛創(chuàng) 建的數(shù)據(jù),生效時間是創(chuàng)建該數(shù)據(jù)的時間,失效時間是9999-12-31。現(xiàn)在對這條數(shù)據(jù)進行了修改,那么我們只需要將當前時間設置為上一個版本的失效時 間,同時創(chuàng)建一條新數(shù)據(jù),生效時間是當前時間,失效時間是9999-12-31即可。

ID 單號 金額 生效時間 失效時間
1 EXP123 100 2013/9/1 15:30:00 9999/12/31 23:59:59

比如上面一條單據(jù),是2013-9-1創(chuàng)建的,后來在2013-9-9 15:00:00對該單據(jù)進行修改,將金額從100修改為120,保存時創(chuàng)建的新數(shù)據(jù)如下:

ID 單號 金額 生效時間 失效時間
1 EXP123 100 2013/9/1 15:30:00 2013/9/9 15:00:00
2 EXP123 120 2013/9/9 15:00:00 9999/12/31 23:59:59

使用了生效、失效時間后,我們可以查詢?nèi)我鈺r刻數(shù)據(jù)庫中數(shù)據(jù)的值,只需要把要查詢的時刻傳入,然后between 生效時間 and 失效時間即可。

使用前兩種方案都需要一個業(yè)務主鍵來標識具體的一個業(yè)務數(shù)據(jù)。如果我們要記錄的實體沒有明確的“單號”、“訂單號”這類的業(yè)務主鍵該怎么辦?我們可以使用創(chuàng)建數(shù)據(jù)時的數(shù)據(jù)庫主鍵作為業(yè)務主鍵。

員工ID 姓名 生日 業(yè)務ID 版本號
1 張三 1984/12/29 1 1

比如我們有個員工表,記錄員工基本信息,在創(chuàng)建張三這個員工的數(shù)據(jù)時,其在數(shù)據(jù)庫的ID為1,那么可以將其業(yè)務ID也設置為1。接下來對張三的屬性進行更改,記錄了版本,那么就會創(chuàng)建新的版本,其主鍵“員工ID”會變化,但是其業(yè)務主鍵“業(yè)務ID”始終是1,不會變化的。

員工ID 姓名 生日 業(yè)務ID 版本號
1 張三 1984/12/29 1 1
2 張三 1985/1/9 1 2

使 用前面兩個方案雖然能夠很好的記錄歷史數(shù)據(jù),但是每次修改數(shù)據(jù)都會導致新版本生成保存,所以每個版本的ID都是新的,所以必須有一個業(yè)務主鍵來標識一個實 體,這里的兩個例子“單號”就是其業(yè)務主鍵。主鍵的變動使得所有關聯(lián)的對象都得變動,從而形成連鎖效應,使得各個關聯(lián)的對象也生成新的版本。比如我們有個 訂單系統(tǒng),里面有訂單表和訂單明細表。現(xiàn)在我們要對訂單的修改記錄歷史版本,所以增加了生效時間和實效時間,并使用訂單號作為業(yè)務主鍵。現(xiàn)在有一個訂單 A,下面有100條明細,如果要對訂單進行修改,將某一條明細的屬性進行修改,從而導致整個訂單的變化,那么我們就需要創(chuàng)建新的訂單數(shù)據(jù)行,由于主鍵變 動,所以訂單明細都需要變動,所以100條明細都需要創(chuàng)建新的版本,新版本的訂單明細中,“訂單ID”指向了新的版本的訂單數(shù)據(jù)的ID。

image

這樣的設計造成的問題就是訂單明細表會極速膨脹,如果一個訂單有1000條明細,我們只是修改了訂單本身的屬性,并不修改訂單明細,也會造成對這1000條明細做Copy,然后保存。那怎么辦呢?我們可以使用以下辦法:

1.對訂單明細建立版本字段,將版本的粒度細化到訂單明細,而不是訂單。訂單與訂單明細不存在數(shù)據(jù)庫級的外鍵關系,只存在業(yè)務級的外鍵關系。也就是說訂單明細表中增加生效時間、失效時間之外,還需要增加“訂單號”這個字段,用于表名該明細是屬于哪個訂單的。

image

我 們這么修改后,如果訂單對象進行了修改,訂單明細沒有修改(比如改了一下收件人信息),那么只需要在訂單表中生成新的一行數(shù)據(jù),訂單明細不會Copy生成 新的數(shù)據(jù)。如果我們對某一條訂單明細進行了更改(比調(diào)整了單價、數(shù)量)那么只需要對具體修改的那條訂單明細進行更改,而不需要對整個訂單的所有明細進行更 改。

使用這種設計后,查詢訂單及其明細,需要對兩個表執(zhí)行生效失效時間的過濾,而且明細的獲取是通過訂單號去取,而不是通過訂單ID去取。

將版本控制的粒度細化到訂單明細時,后臺程序的邏輯也會更加復雜。用戶在界面上操作的是訂單對象,系統(tǒng)會將整個修改后的訂單對象傳到后臺,后臺程序需要對每個訂單項進行對比,如果發(fā)現(xiàn)訂單項進行了修改,那么就會調(diào)用生成新版本訂單明細的方法。

2.使用單獨的歷史表

這是另外一種實現(xiàn)歷史版本記錄的方法:

三、使用單獨的歷史表

使 用歷史表其實就是建立完全相同Schema的表(當然,也可以添加更多的字段用于記錄額外的歷史版本信息),該表只保留歷史版本的數(shù)據(jù)。這有點像一個歸檔 邏輯,所有歷史版本我們認為都應該是不經(jīng)常訪問的,所有可以扔到單獨的表,對于現(xiàn)有生效的版本,仍然保留在原表中,如果需要查詢歷史版本,那么就從歷史表 中查詢。

使用單獨的歷史表有以下好處:

  • 業(yè)務數(shù)據(jù)表的數(shù)據(jù)量不會因為歷史版本記錄而膨脹。因為歷史數(shù)據(jù)都記錄到了另外一個表中,所以業(yè)務數(shù)據(jù)表只記錄了一份數(shù)據(jù)。
  • 業(yè)務數(shù)據(jù)表的Schema不需要調(diào)整,增加額外的版本字段。由于對原有數(shù)據(jù)表不做Schema變更,所以原有查詢邏輯也不用更改。對于一個現(xiàn)有的數(shù)據(jù)庫設計,在增加歷史數(shù)據(jù)記錄功能時更簡單。
  • 業(yè)務數(shù)據(jù)表可以直接進行update操作,不會生成新的ID。由于ID不會變,所以我們并需要業(yè)務主鍵應用到程序邏輯中。

使 用歷史表記錄歷史版本主要是要對數(shù)據(jù)操作方法(增加、刪除、修改)進行修改,使得每次數(shù)據(jù)操作時,先在歷史表中留痕,然后再進行數(shù)據(jù)操作。另外就是對查詢 歷史版本功能進行修改,因為歷史數(shù)據(jù)在另外一個表中,所以對于的SQL是不一樣的。當然,我們也可以創(chuàng)建歷史版本數(shù)據(jù)庫,里面保存了所有的歷史表。

數(shù)據(jù)庫模型設計——歷史與版本設計


更多文章、技術交流、商務合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 久久久久久久久免费视频 | 久久96精品国产 | 香蕉在线精品一区二区 | 国产日韩欧美一区二区 | 久久久综合中文字幕久久 | 免费国产小视频在线观看 | 国产一区二区三区在线影院 | 国农村精品国产自线拍 | 欧美精品成人久久网站 | 青草福利 | 国产99在线 | dyav午夜片 | 日本不卡免费高清视频 | 国产欧美另类久久久品 | 久久日本经典片免费看 | 亚洲综合春色另类久久 | 日本亚洲欧洲高清有码在线播放 | 国产呦系列 欧美呦 日韩呦 | 亚洲精品国产一区二区在线 | 曰批免费视频播放在线看片 | 国内免费一区二区三区视频 | 欧美性禁片在线观看 | 中文乱码精品一区二区三区 | 久久综合色婷婷 | 国内精品视频九九九九 | 国产男女猛视频在线观看网站 | 中文字幕欧美日韩高清 | 成人区在线观看免费视频 | 久久国产精品自由自在 | 亚洲精品久久激情影院 | 97影院支持微信微博观看 | 国产日产亚洲精品 | 中文字幕亚韩 | 中文字幕精品视频在线观 | 99re国产精品视频首页 | 久久艹在线 | 亚洲天堂久久久 | 四虎在线最新地址4hu | 日日摸日日碰夜夜爽久久 | 亚洲一成人毛片 | 九九久久国产精品 |