【发布时间】:2011-03-30 09:08:01
【问题描述】:
假设我有两张桌子,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;
这对于强制执行数据完整性等非常有用,但我希望能够“删除”用户并保留其所有 cmets(仅供参考)。
为此,我添加了deleted,以便我可以在记录中使用SET deleted = 1。通过默认使用deleted = 0 列出所有内容,我可以隐藏所有已删除的记录,直到我需要它们。
到目前为止一切顺利。
问题来了:
- 用户使用用户名(例如“Sam”)注册,
- 我软删除了该用户(出于不相关的原因),并且
- 其他人以 Sam 的身份注册,突然我们违反了
user的 UNIQUE 约束。
我希望用户能够编辑自己的用户名,所以我不应该将username作为主键,删除用户时我们仍然会遇到同样的问题。
有什么想法吗?
编辑澄清:在下面添加了 RedFilter 的答案和 cmets。
我担心“已删除”的用户和 cmets 对公众不可见,但只有管理员可见,或者为了计算统计数据而保留。
这个问题是一个思想实验,用户和评论表只是示例。尽管如此,username 并不是最好用的。 RedFilter 对用户身份提出了有效的观点,尤其是当记录在公共环境中呈现时。
关于“为什么用户名不是主键?”:这只是一个示例,但如果我将其应用于实际问题,我将需要在假设存在代理主键的现有系统。
【问题讨论】:
标签: mysql database-design foreign-keys constraints