4

这就是我想要做的事:如何使用自动增加的主键作为外键?

我有2个表...

CREATE TABLE `parent` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `data` text, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; 

CREATE TABLE `child` (
    `parent_id` int(11) DEFAULT NULL, 
    `related_ids` int(11) DEFAULT NULL, 
    KEY `parent_id` (`parent_id`), 
    KEY `related_ids` (`related_ids`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

然后约束:

ALTER TABLE `parent` ADD FOREIGN KEY (`id`) REFERENCES `child` (`parent_id`); 

正如你可以看到父表具有一个自动递增的主键“id”,它也被用作子表的外键。

现在我想在父表中插入一条记录,像这样:

INSERT INTO parent SET DATA="abc"; 

它失败,错误:

Cannot add or update a child row: a foreign key constraint fails (anacorbero . parent , CONSTRAINT parent_ibfk_1 FOREIGN KEY (id) REFERENCES child (parent_id))

我所知,这是因为它没有找到失败子表中的引用记录。如果我通过在子表中创建一条记录开始,将它的parent_id设置为1,然后重置父表的自动递增计数器(以便下一个插入将具有id = 1),它就可以工作!但这不是一个解决方案。

我没有看到插入阻塞,如果没有相关的行中的子表的工具...

我只是试图做一个一对多的关系...

(我知道我可以使用加入,但我想用表关系,为数据的完整性,也作为PHP元)

回答

8

看起来你有引用和反向引用的表。你可能想要做的:

ALTER TABLE `child ` ADD FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`); 

您还可以定义在CREATE TABLE声明外键,如下所示:

CREATE TABLE `parent` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `data` text, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; 

CREATE TABLE `child` (
    `parent_id` int(11) DEFAULT NULL, 
    `related_ids` int(11) DEFAULT NULL, 
    KEY `parent_id` (`parent_id`), 
    KEY `related_ids` (`related_ids`), 
    FOREIGN KEY (`parent_id`) REFERENCES `parent`(`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

测试用例:

INSERT INTO parent (`data`) VALUES ('test data 1'); 
Query OK, 1 row affected (0.01 sec) 

INSERT INTO parent (`data`) VALUES ('test data 2'); 
Query OK, 1 row affected (0.01 sec) 

INSERT INTO child (`parent_id`, `related_ids`) VALUES (1, 100); 
Query OK, 1 row affected (0.01 sec) 

INSERT INTO child (`parent_id`, `related_ids`) VALUES (2, 100); 
Query OK, 1 row affected (0.01 sec) 

INSERT INTO child (`parent_id`, `related_ids`) VALUES (3, 100); 
ERROR 1452 (23000): Cannot add or update a child row: 
    a foreign key constraint fails 
+0

+1:当我读到你的答案时,我意识到我误读了这个问题。 – 2010-08-23 02:23:32

+0

感谢您的快速回答。我只是意识到我自己! – Rolf 2010-08-23 02:26:41

+0

我已经在SQL Server 2012中定义了身份,但我试图将一些值传递给db。所以在那个地方(自动递增),我需要通过什么? – 2013-12-11 15:24:11

1

呃......我我认为我把它倒过来了。 看来,我需要外键添加到子表,这样的:

ALTER TABLE `child` ADD FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`); 

我有一个很难对付的MySQL术语。你能怪我吗?

+1

我很高兴你意识到问题所在。如果你仔细想想,这并不难理解。外键是**约束**。并且你将在'child'表上添加约束,因为'child'表的'parent'字段将被限制为仅当该值存在于'parent'的'id'列时才接受值表。 – 2010-08-23 02:27:28