假設我有兩個表,user
和comment
。他們有看起來像這樣的表定義:MySQL軟刪除,唯一鍵和外鍵約束
CREATE TABLE `user` (
`id` INTEGER NOT NULL AUTO_INCREMENT,
`username` VARCHAR(255) NOT NULL,
`deleted` TINYINT(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
UNIQUE KEY (`username`)
) ENGINE=InnoDB;
CREATE TABLE `comment` (
`id` INTEGER NOT NULL AUTO_INCREMENT,
`user_id` INTEGER NOT NULL,
`comment` TEXT,
`deleted` TINYINT(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
CONSTRAINT `fk_comment_user_id` FOREIGN KEY (`user_id`)
REFERENCES `user` (`id`)
ON DELETE CASCADE
ON UPDATE CASCADE
) ENGINE=InnoDB;
這是偉大的強制執行數據的完整性和所有這一切,但我希望能夠以「刪除」用戶,並保持其所有評論(供參考的清酒)。
爲此,我添加了deleted
以便我可以在記錄上SET deleted = 1
。通過默認列出一切與deleted = 0
,我可以隱藏所有刪除的記錄,直到我需要他們。
到目前爲止這麼好。
問題是當:
- 用戶登錄了一個用戶名(比如,「薩姆」),
- 我軟刪除用戶(不相關的原因),並
- 有人否則會以Sam身份註冊,突然我們違反了
user
上的UNIQUE約束。
我希望用戶能夠編輯自己的用戶名,所以我不應該讓username
主鍵和刪除用戶的時候我們仍然有同樣的問題。
有什麼想法?
編輯澄清:添加以下RedFilter的答案,下面的評論。
我關心的情況是,「刪除」的用戶和評論對公衆不可見,但只有管理員可見,或者爲了計算統計而保留。
這個問題是一個思想實驗,用戶和評論表僅僅是示例。儘管如此,username
並不是最好的選擇; RedFilter提供有關用戶身份的有效信息,特別是當記錄顯示在公共場合時。
關於「爲什麼不是用戶名的主鍵?」:這只是一個例子,但如果我申請這一個真正的問題,我會需要到它假定現有系統的約束下工作代理主鍵的存在。
將'deleted'的字段類型更改爲'timestamp'可讓您在此處添加更多已刪除的行。如果你想要現有的(未刪除的)記錄,請在這個字段中檢查'null'。 – 2013-01-02 06:57:08
@TahaPaksu如果您允許刪除空值,您將失去唯一密鑰的值。 – 2016-03-15 20:18:46
@eric_s這種方法需要像「除1之外的所有東西都被視爲'未被刪除'」。 – 2016-03-16 06:21:22