巧用*_his表記錄操做歷史

文章轉載自「開發者圓桌」一個關於開發者入門、進階、踩坑的微信公衆號數據庫

許多OLTP應用的開發者都知道,一些重要的操做要記錄操做歷史,把操做前的數據備份到歷史表,而後再執行相應的修改操做。這樣能夠獲取某個時點的操做日誌和操做前的記錄值。微信

 

要記錄操做歷史有兩個層面,一個是應用層即經過應用程序邏輯實現歷史記錄的保存,一個是數據庫層即數據庫歸檔、審計等DBA管理的功能。這裏僅討論前者。測試

 

好比有一個用戶表t_user包含id,name,sex,age字段,由於t_user表的修改很是重要,要記錄操做歷史,通常的作法是創建和t_user結構相同的一個歷史表命名爲t_user_his,它包含id,name,sex,age字段,同時添加對應的his_id,oper_time,oper_remark等記錄操做說明的字段。設計

 

OK,表設計完畢了,咱們須要在修改時記錄用戶以前的信息,通常的作法是先來個insert插入歷史表,而後再去修改原表數據,把這兩個操做放到同一個事務中去處理,釋義代碼以下:日誌

setAutoCommit(false);blog

insert into t_user_his(id,name,sex,age,his_id,oper_time,oper_remark) select id,name,sex,age,'歷史表id',timestamp,'修改姓名' from t_user where id=18970;事務

update t_user set name='xxx' where id=18970;開發

commit();rem

部署上線一切運行正常,領導很是滿意,忽然有一天須要在t_user中添加一個phone字段來記錄用戶的電話號碼,軟件產品惟一不變的就是下面這個詞部署

沒辦法只能修改了,須要按照下面幾個步驟修改:

首先,修改t_user表添加一個phone字段。

其次,修改t_user_his表添加一個phone字段。

第三,修改涉及到的記錄操做歷史的SQL,若是有多處也須要一併修改:

setAutoCommit(false);

insert into t_user_his(id,name,sex,age,phone,his_id,oper_time,oper_remark) select id,name,sex,age,phone,'歷史表id',timestamp,'修改姓名' from t_user where id=18970;

update t_user set name='xxx' where id=18970;

commit();

最後,編譯程序,測試,提交,部署上線,一個流程下來可能要好多天。

 

問題來了,只能這樣處理嗎?如何規避字段修改帶來的重複修改呢?有沒有更好的解決方案呢?答案是確定的,只須要經過一個簡單的修改就能夠作到。

 

咱們能夠這樣來設計t_user_his表的字段,把歷史操做相關字段前置,後續字段保持與t_user徹底一致,例如t_user_his字段能夠這樣安排:his_id,oper_time,oper_remark,id,name,sex,age。

 

應用程序修改以下:

setAutoCommit(false);

insert into t_user_his select ,'歷史表id',timestamp,'修改姓名' ,a.* from t_user a  where id=18970;

update t_user set name='xxx' where id=18970;

commit();

這樣的話,要添加一個新的phone字段,該如何操做呢?

首先,修改t_user表添加一個phone字段。

其次,修改t_user_his表添加一個phone字段與t_user字段順序一致。

 

好了,兩步就能夠實現字段的自由添加、修改或者刪除,不須要修改任何應用程序代碼,也再也不須要複雜的部署、測試、上線流程,僅在數據庫中完成操做就能夠了。

 

上述方法,修改一個字段就要記錄整條數據到歷史表,會佔用較多的空間,要麼就把字段寫死。具體如何選擇仍是要分析系統的業務要求,不可盲目照搬。

相關文章
相關標籤/搜索