假设我有两张表,user
和comment
它们的表定义如下:
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”以便我可以在记录上设置“deleted = 1”。通过默认列出所有具有“deleted = 0”的内容,我可以隐藏所有已删除的记录直到需要它们时。
目前为止还不错。
问题出现在以下情况:
- 用户使用用户名注册(比如说,“Sam”), - 我软删除该用户(由于与其无关的原因),并且 - 其他人来注册一个名为 Sam 的账户,这时我们就违反了 user 上的唯一约束条件。
我希望用户能够编辑自己的用户名,因此不应将“username”作为主键,当删除用户时仍会遇到相同的问题。
有什么想法吗?
编辑以澄清:我关注的是“已删除”的用户和评论不可见于公众,而只对管理员可见或用于计算统计信息的情况。
本问题是个思维实验,用户和评论表只是示例。然而,选择“username”并不是最好的,RedFilter提出了关于用户身份的合理观点,特别是当记录在公共环境中呈现时。关于“为什么不把用户名设为主键?”:这只是一个例子,但如果将其应用于真实问题,则需要在假定存在代理主键的现有系统约束内进行工作。
deleted
字段类型更改为timestamp
可以让你在那里添加更多已删除的行。如果你想获取现有(未删除)记录,请检查此字段中是否为空值。 - Taha Paksu