轉自:https://www.v2ex.com/t/410612
鋪墊
本人不才,不知這個“邏輯刪除”詞用的對不對,想表達的就是:當刪除時只是將 is_deleted 字段設置為 1,而不是真的將這條記錄刪掉,關鍵詞可能是 logic delete 或 soft delete。
問題
-
查了一些資料,貌似支持“邏輯刪除”觀點的人是多數的:
-
有前輩提到一個觀點,真實世界是沒有刪除的。訂單作廢,用戶禁用,員工離職,文稿廢棄,優惠券作廢都是狀態的變化。所以 SQL 里面 DELETE 在業務場景里都不應該出現。
-
為了安全,生產環境不能有人或有程序是對數據庫的表有 DELETE 權限的。
-
-
反對的聲音還是有的:
-
邏輯刪除的設計還會導致常用的 unique key 失效(當然用戶可將數據行中原來的碼和 is_deleted 一起作為 unique key,但是這樣又會出現,再次刪除時,系統中無法出現兩個完全相同的 ID,又都是 is_deleted=1 的記錄出現)。
-
被“刪除”的這條記錄如果在業務中與大量的表有關聯關系,那么在刪除它時,就會引發很多的級聯的更新,或者判斷引用並提示用戶無法修改正被引用的資源。而要保證這些全部更新無誤,又要求事務一定可靠,若產生了狀態不一致,那么這些“臟數據”的維護也是很痛苦的。
-
當表中的記錄數越來越大時,查詢起來會越來越慢。
-
求解
我能理解具體問題需要具體分析,是要“邏輯刪除”還是“物理刪除”,主要還是要根據實際的業務場景,比如互聯網企業搜 /收集的個人信息、電商類平台用戶的訂單、金融類平台的交易記錄,肯定是不能刪除的。但是對於一些維護中間狀態的數據,如果可以通過記錄日志實現“留檔”那么就可以真的刪掉它。
不知道有沒有那種開源組件,可以_自動實現_當我從一個表中物理刪除一條記錄時,它可以幫我將它轉移到備份表中,我看了一個 MySQL 的審計插件,但是好像並不做這個用途的。或者有類似“ commit log ”那種東東,刪除時只需要記錄一個 log,有需要的時候可以從日志中恢復回來。
參考
下附幾個我搜過的資料,希望能幫助和我一樣迷茫的童鞋:
-
“別刪除數據” http://www.infoq.com/cn/news/2009/09/Do-Not-Delete-Data
-
“邏輯刪除真的不是一個好的設計 - 簡書” http://www.jianshu.com/p/f37281576585
-
“ MySQL 刪除數據是加一個字段做標記,還是將刪除的數據插入到另外一張備份表里,哪種方案更好? - V2EX ”https://fast.v2ex.com/t/406208
-
“不做顯式刪除,而用 status=0 代替,是好的實踐么? - V2EX ” https://www.v2ex.com/t/363226