【问题标题】:parent_id a foreign key(self reference) and null?parent_id 一个外键(自引用)和空值?
【发布时间】: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 tableinsert 语句按照您执行它们的顺序,因此您正在尝试的内容是可重现的)。

标签: mysql sql database-design


【解决方案1】:

在这个 CW 答案中从上面的 cmets 中收集一些结论。

【讨论】:

  • 谢谢先生。第一次与我正在阅读的书的作者交谈。昨天在评论部分消除了疑虑,但必须补充说,让您指出是一种荣幸。再次感谢。
猜你喜欢
  • 2017-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多