Mysql 如何管理新生成密钥的外键关系? 出身背景
我有两个表Mysql 如何管理新生成密钥的外键关系? 出身背景,mysql,sql,innodb,mysql-8.0,Mysql,Sql,Innodb,Mysql 8.0,我有两个表Parent和Child。该关系是一对多父ID到子ID的关系。所以,为了优化例程JOIN查询,我考虑通过 ALTER TABLE Child ADD CONSTRAINT FOREIGN KEY parent_id REFERENCES Parent (id); 其中Parent.id是主键。通过不显式地设置更新时的或删除时的子句,我相信我已经隐式地设置了 ON DELETE NO ACTION ON UPDATE NO ACTION 是的。请注意,Child.pare
Parent
和Child
。该关系是一对多父ID到子ID的关系。所以,为了优化例程JOIN
查询,我考虑通过
ALTER TABLE Child
ADD CONSTRAINT FOREIGN KEY
parent_id
REFERENCES Parent (id);
其中Parent.id
是主键
。通过不显式地设置更新时的或删除时的子句,我相信我已经隐式地设置了
ON DELETE NO ACTION
ON UPDATE NO ACTION
是的。请注意,Child.parent\u id
已编制索引
但是这种情况是这样的,子表将在父表
之前频繁更新,并且有时会有关于父表
的新数据,其中包含以前从未见过的Child.Parent\u id
外键。这是因为Child
表是类似于事务的记录的近乎即时的日志,这些记录是数据库的唯一输入;父表
是子表
的派生和合并摘要,其任务是每隔几小时更新一次
现在,在阅读其他文章时,我已经了解到,外键
要求父表的引用列是唯一的并且存在。很明显,我对唯一性没有问题,因为我引用的父列是主键
,所以我的问题是引用值的存在。在一个问题中:当我将一条新记录插入包含一个从未见过的Child.parent\u id
的表时会发生什么
实验
我在两个较小的表上进行了测试,这两个表都是在我希望优化的较大表的映像中创建的(使用创建表父级,如…
,等等)。这些测试表的命名如上所述。创建这些小测试表后,我在测试表上定义了一个外键
,与上面的完全相同
因此,Parent
看起来像:
| id | SummaryStat1 | SummaryStat2 | ... | SummaryStatN |
|-------|--------------|--------------|-----|---------------------|
| 147 | 50.4 | 1999983 | ... | NULL |
| 99384 | 60.8 | 3592324 | ... | 2018-03-05 00:22:09 |
| ... | | | | |
和Child
类似:
| id | parent_id | Stat1 | ... | StatM |
|-------------|-----------|-------|-----|---------------------|
| 1 | 147 | 18.3 | ... | 2018-02-17 14:23:10 |
| 2 | 99384 | 0.02 | ... | 2018-02-17 14:23:12 |
| (AUTO INCR) | ... | ... | ... | ... |
| 70565 | 147 | | | 2018-02-18 16:59:00 |
| ... | ... | ... | ... | ... |
因此,在设置了外键之后,我在子项中插入了一条新记录,其中包含了一个从未见过的子项。父项id
,数据库发出了预期的投诉:
"Cannot add or update a child row: a foreign key constraint fails..."
这方面有什么著名的工作吗?我正在考虑修改事务处理,在将数据发送到子表之前,插入带有新Parent.id
的默认Parent
记录,但如果有一个简单的DB解决方案,那就更好了,类似于一个选项,允许您存储断开连接的外键值,直到父外键出现在父表中。没有“简单”解决方案
BEGIN;
INSERT INTO parent ...
ON DUPLICATE KEY UPDATE
id = LAST_INSERT_ID(id);
$parent_id = SELECT LAST_INSERT_ID();
INSERT INTO child
( ..., parent_id, ... )
VALUES
( ..., $parent_id, ... )
COMMIT;
不存在断开外键连接的情况-数据库始终施加完整性约束。在创建父项之前,您可以将child.parent\u id
设置为NULL。但是,在创建父项时,您将如何更新child.parent\u id
?我认为您的子项和父项相反。如果我将child.parent\u id
设置为NULL
,然后创建父项,无法立即将父级连接回该子级。我仅获取子信息,父信息必须从该父信息派生。抱歉,更正:“…父信息必须从子表派生。”