如何解決邏輯刪除與數據庫惟一約束衝突

前言

不知道你們有沒有遇到這麼一種業務場景,在業務中有個惟一約束A,當該業務進行邏輯刪除後(設置標記爲刪除狀態),再往惟一約束列插入相同的值時,此時會報Duplicate entry,但在業務上,該值時必需要插入的。今天咱們就來聊聊處理這種業務場景的幾種思路redis

解決思路

方案一:不採用邏輯刪除,直接物理刪除

方案二:新建歷史表

主表進行物理刪除,同時將刪除的記錄保存到歷史表中數據庫

方案三:取消表的惟一約束,同時引入redis來保證惟一約束

取消表的惟一約束,在項目中引入redis,經過redis來判重,新增時往redis set記錄,刪除時,刪除redis記錄class

方案四:變動刪除標記爲時間戳

將刪除狀態不以0,1表示,而是以時間戳爲值,而後將刪除狀態爲與以前的惟一約束A從新組成惟一聯合約束index(A、del_flag),刪除時變動del_flag的時間戳時間戳

方案五:保留刪除標記,同時新建一個字段del_unique_key

保留刪除狀態位,再新增一個字段del_unique_key,該字段默認值爲0,字段類型和大小與主鍵id保持一致,同時與原先的惟一約束從新組成聯合惟一約束index(A,del_unique_key),業務進行邏輯刪除,變動del_unique_key的值爲該刪除行的主鍵id數據

方案的取捨

方案一得從業務的角度上考慮了,若是物理刪除,對業務無損,那就無所謂了。方案二等於須要刪除的記錄的表都須要有歷史表,若是僅僅是用來實現記錄刪除記錄,感受有點大材小用。方案三引入redis,雖然也能夠解決問題,可是又額外增長複雜度,同時還得保證redis和數據庫的一致性。方案四和方案五其實實現的思路是同樣,不過若是已是在線上跑的業務,仍是推薦用第五種方案,畢竟新增字段正常對已有的業務影響相對較小,若是是第四種方案,直接將標誌位修改成時間戳,可能還會涉及改業務。若是是新增業務,第四種和第五種方案比較推薦項目

相關文章
相關標籤/搜索