如何使用自动递增主键作为外键?

发布于 2024-09-15 16:46:42 字数 1125 浏览 3 评论 0原文

这就是我想要做的:

我有 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";

它失败并出现错误:

无法添加或更新子行:a 外键约束失败 (myschema.parent, 约束 parent_ibfk_1 外键 (id) 参考child (parent_id))

我知道它失败是因为它在子表中找不到引用的记录。如果我首先在子表中创建一条记录,将其parent_id设置为1,然后重置父表的自动增量计数器(以便下一次插入的id = 1),它就可以了!但这不是解决方案。

如果子表中没有相关行,我看不到插入阻塞的实用性...

我只是试图建立一对多关系...

(我知道我可以使用 JOIN,但是我正在尝试使用表关系来保证数据完整性并作为 PHP 的元数据)

This is what I'm trying to do:

I have 2 tables...

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;

And then a constraint:

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

As you can see the table parent has an auto-incremented primary key "id", which is also being used as a foreign key for the child table.

Now I want to insert a record in the parent table, like this:

INSERT INTO parent SET DATA="abc";

And it fails with error:

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

I understand that it fails because it doesn't find a referred record in the child table. If I start by creating a record in the child table, set it's parent_id to 1, then reset the auto-increment counter of the parent table (so that the next insert will have id = 1), it works! But that's not a solution.

I don't see the utility of the insert blocking if there is no related row in the child table...

I'm just trying to do a one-to-many relationship...

(I know I can use JOIN, but I'm trying to use table relations, for data integrity and also as metadata for PHP)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

合久必婚 2024-09-22 16:46:42

看起来您的引用表和被引用表是相反的。您可能想要这样做:

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 

It looks like you have the referencing and referenced tables in reverse. You may want to do:

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

You can also define the foreign key in the CREATE TABLE statement, as follows:

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;

Test case:

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 
空城缀染半城烟沙 2024-09-22 16:46:42

呃……我想我搞反了。
看来我需要将外键添加到子表中,就像这样:

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

我很难处理 MySQL 术语。你能怪我吗?

Uh... I think I got it backwards.
It seems that I need to add the foreign key to the child table, like that:

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

I'm having a hard time dealing with MySQL terminology. Can you blame me?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文