僅當列具有特定值時 MySQL 唯一索引
我有一個表,我在其中使用布爾列
deleted
來表示特定記錄是否已被使用者“刪除”(意思是,它出現在垃圾列表而不是普通列表中)。這些物品都有應該是獨一無二的蛞蝓。但是,如果使用者想要添加一個帶有與已刪除記錄的 slug 相同的 slug 的項目,則應該允許它。我嘗試使用 UNIQUE 索引來執行此操作
deleted
,slug
但是,如果該項目將被刪除,則會出現問題:垃圾列表中應該有兩個項目具有相同的 slug,這將違反約束。所以實際上我需要一個僅適用於
deleted
=0的記錄的約束我已經看到了自定義唯一列約束的問題,僅當一列具有特定值時才強制執行,但是,它僅適用於 PostgreSQL 並且我在 MySQL 上。MySQL中有沒有辦法做到這一點,或者一個很好的解決方法?
我想製作
deleted
一個整數而不是布爾值,其中 0 表示not deleted和任何其他數字deleted。然後,具有相同 slug 的已刪除項目在列中可能具有不同的值deleted
。但是,這意味著介面軟體(用 PHP 編寫)必須檢查
deleted
如果發生約束衝突,它可以在列中放入什麼,當然我更喜歡純 MySQL 解決方案。如果無論如何我要在 PHP 程式碼中編寫它,我寧願更改slug
值,例如,id
在刪除項目時將記錄添加到 slug - 或者,為已刪除的項目創建第二個表記錄,其中不存在此類約束。無論如何,有沒有一種純粹的 MySQL 方法可以做到這一點?
注意:當然,當使用者請求恢復以前刪除的項目時,當它的 slug 已經分配給新記錄時,這種方案會遇到困難。無論如何,這必須在介面程式碼中完成。
如果您有生成唯一整數的方法,則不必檢查可以在“已刪除”中使用的值,而 MySQL 確實…該函式每次呼叫時都會
UUID_SHORT()
生成一個唯一且單調的值。BIGINT UNSIGNED
該函式適用於每秒 1670 萬個新值,只要
@@SERVER_ID
保持不變並且您不關閉伺服器,將系統時鐘向後設置,就永遠不會返回重複的(或小於以前的)值及時,並重新啟動伺服器……即使你這樣做,重複值的機率仍然很小,但不再是真正不可能的。您還可以在 MySQL 5.6 上將“已刪除”設置為 a
DATETIME(6)
或TIMESTAMP(6)
,使用 ‘0000-00-00 00:00:00.000000’ 表示“未刪除”並NOW()
表示已刪除。盡我所能,我無法讓 MySQL 產生
NOW()
精確到微秒的衝突。