【发布时间】:2017-12-10 06:04:36
【问题描述】:
通过 Bill Karwin 的书“SQL 反模式”,第 3 章,朴素树(邻接表,父子关系),有一个注释表的示例。
CREATE TABLE Comments (
comment_id SERIAL PRIMARY KEY,
parent_id BIGINT UNSIGNED,
comment TEXT NOT NULL,
FOREIGN KEY (parent_id) REFERENCES Comments(comment_id)
);
样本数据
| comment_id | parent_id | comments
|------------| ----------|-------------------------------------
|1 | NULL |What’s the cause of this bug?
|2 | 1 |I think it's a null pointer
|3 | 2 |No, I checked for that
|4 | 1 |We need to check for invalid input
|5 | 4 |Yes,that's a bug
|6 | 4 |Yes, please add a check
|7 | 6 |That fixed it
该表有一个comment_id、parent_id 和一个comment 列。 parent_id 是引用comment_id 的外键。
comment_id 从 1 开始自动递增。
问题。
如果 parent_id 应该是引用 comment_id 的外键,那么当使用外键的目的是确保引用完整性时,comment_id = 1 的行怎么会有 parent_id null/0。
注意:我按原样创建表并尝试输入数据并收到此错误
#1452 - 无法添加或更新子行:外键约束失败(`category`.`cmets`, CONSTRAINT `cmets_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `cmets` (`comment_id`))
【问题讨论】:
-
如果不为空,它会是什么?它只能与comment_Id 相同。但由于 comment_id 是一个自增列,所以不能这样做。
-
请注意,设置 FK 时,两种列类型应该相同。在你的情况下,一个是
SERIAL,另一个是BIGINT UNSIGNED -
@AlexTartan,感谢您的提醒,我从书中复制了准确的表格。是的,两个列类型应该相同。
-
null 和 0 是完全不同的东西。 null 是一个未知值,这就是为什么即使引用的列没有 null 值,它也可以在外键中使用。 0 不为空,如果您尝试将 0 放在他的 parent_id 列中,您将在问题中得到错误。
-
代码和数据都很好并且可以工作。同样
SERIAL只是BIGINT UNSIGNED类型的自动增量列的缩写形式。正如其他人提到的,确保使用null,而不是0作为您的根条目。而且您必须以正确的顺序输入数据。因此,请添加您正在使用的代码直到出现错误(例如,create table和insert语句按照您执行它们的顺序,因此您正在尝试的内容是可重现的)。
标签: mysql sql database-design