【问题标题】:FOREIGN KEY references same table's column. Can't insert valuesFOREIGN KEY 引用同一个表的列。无法插入值
【发布时间】:2013-01-03 12:28:18
【问题描述】:

我用 FOREIGN KEY 创建了表,但不能插入任何东西。

CREATE TABLE menus (

id int(10),
parent_id int(10),
label varchar(255),
PRIMARY KEY (id),
FOREIGN KEY (parent_id) REFERENCES menus (id)
);

我需要 FOREIGN KEY 在删除父级时自动删除子级。此表已成功创建,但我无法插入任何内容。

INSERT INTO `menus` (`parent_id`, `label`)
VALUES ('1', 'label1');

INSERT INTO `menus` (`label`)
VALUES ( 'label1');
#1452 - Cannot add or update a child row: a foreign key constraint fails

我真的不想在 php 代码中寻找任何孩子,所以我需要以某种方式创建一个包含 3 列的简单表格,并自动删除所有孩子和他们的孩子。

【问题讨论】:

  • 您说要“自动删除子项”,但您向我们展示的只是插入内容。你的问题到底是什么?
  • 通常,您需要允许“根”记录有一个空父记录 - 即menus.parent_id 应该可以为空,而“根”菜单项将有一个空parent_id
  • 您希望 id 具有哪些值?我没有看到它们中的任何一个插入或自动生成
  • 我认为你错过了 id 列的自动增量

标签: mysql foreign-keys cascade


【解决方案1】:

对于您的所有需求,您应该采用这种结构

CREATE TABLE `menus` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `parent_id` int(11) unsigned DEFAULT NULL,
  `label` varchar(255) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`),
  KEY `fk_parent_menu` (`parent_id`),
  CONSTRAINT `fk_parent_menu` FOREIGN KEY (`parent_id`) 
    REFERENCES `menus` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
);

SQL Fiddle DEMO

Demo展示了父节点的插入和删除

所有孩子的魔法掉落部分由ON DELETE CASCADE完成

【讨论】:

  • @SirRufo 它不适用于update。检查sqlfiddle.com/#!9/445052/1/0 然后尝试添加Update menus set id = 6 WHERE id = 1; 你会得到#1451 - Cannot delete or update a parent row
  • @Sam 不能用于更新身份字段。为什么要更新/更改自动生成的身份字段的值?
  • @SirRufo 完全同意你的观点,在实际情况下,PK 永远不会更新。只是想添加此评论以提及这是 mysql 中已知的 documented 限制(或 bug )。
【解决方案2】:

通常,您需要允许“根”记录有一个空父记录 - 即 menus.parent_id 应该可以为空,而“根”菜单项将有一个空 parent_id

将您的 DDL 更改为:

 parent_id int(10) NULL

然后你将你的根元素添加为 NULL 作为 parent_id

insert into `menus` (id, `label`, parent_id)
VALUES (1, 'label1', null);

那么你最好使用子元素:

insert into `menus` (id, `label`, parent_id)
VALUES (2, 'subitem1', 1);

等等

SQL Fiddle here

【讨论】:

  • parent_id 已经可以为空(默认情况下)。如您所说,插入代码中的错误是正确的。
  • 这只是一半,缺少自动删除子项 :o)
猜你喜欢
  • 2016-11-12
  • 2014-03-20
  • 1970-01-01
  • 1970-01-01
  • 2010-09-20
  • 2019-10-05
  • 2017-04-15
  • 2018-08-08
  • 1970-01-01
相关资源
最近更新 更多