简体   繁体   English

MySQL:在具有多个外键依赖项的表上更新

[英]MySQL: update on a table with multiple foreign key dependencies

Below is the simplified picture of the relationships I have in my DB: 下面是我在数据库中的关系的简化图:

create table attribute (id int auto_increment, primary key (id));
create table state_sample (id int auto_increment, primary key(id));
create table state_sample_attribute (
    state_sample_id int,
    attribute_id int,
    primary key(state_sample_id, attribute_id),
    foreign key (state_sample_id) references state_sample(id) on update cascade,
    foreign key (attribute_id) references attribute(id) on update cascade
);
create table note (
    id int auto_increment,
    state_sample_id int,
    attribute_id int,
    primary key(id),
    foreign key (state_sample_id) references state_sample(id) on update cascade,
    foreign key (state_sample_id, attribute_id)
        references state_sample_attribute(state_sample_id, attribute_id) on update cascade
);

insert into attribute values (1);
insert into state_sample values (1);
insert into state_sample_attribute values (1, 1);
insert into note values (1, 1, 1);

Whenever I try to update the ss table, it fails: 每当我尝试更新ss表时,它都会失败:

update state_sample set id = 2;

ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`demotemplate`.`note`, CONSTRAINT `note_ibfk_1` FOREIGN KEY (`ss_id`) REFERENCES `ss` (`id`) ON UPDATE CASCADE) 错误1452(23000):无法添加或更新子行:外键约束失败(`demotemplate`.`note`,CONSTRAINT`note_ibfk_1`外国密钥(`ss_id`)参考`ss`(`id`)更新级联)

As far as I understand, this is what happens: 据我了解,这是发生了什么:

  • It tries to set state_sample.id = 2. 它尝试设置state_sample.id = 2。
  • It sees the cascade to note and tries to update note.state_sample_id. 它看到要注意的级联,并尝试更新note.state_sample_id。
  • However, note.state_sample_id is also involved in the foreign key to to state_sample_attribute(state_sample_id, attribute_id), so it goes to check whether that's still valid. 但是,note.state_sample_id也涉及到state_sample_attribute(state_sample_id,attribute_id)的外键,因此它会检查它是否仍然有效。
  • As state_sample_attribute.state_sample_id has not yet been updated, the constraint fails. 由于state_sample_attribute.state_sample_id尚未更新,因此约束失败。

Is my assumption correct? 我的假设正确吗? And if so, is there a way to work this around? 如果是这样,是否有解决此问题的方法?

Give the ssa table its own id primary key, and use that in the foreign key in notes , rather than referencing the ss_id and a_id columns. ssa表自己的id主键,并在notes的外键中使用它,而不是引用ss_ida_id列。

create table ssa (
    id int auto_increment,
    ss_id int, 
    a_id int, 
    primary key (id),
    unique key (ss_id, a_id), 
    foreign key (ss_id) references ss(id) on update cascade, 
    foreign key (a_id) references a(id) on update cascade);
create table note (
    id int auto_increment, 
    ss_id int, 
    ssa_id int, 
    primary key(id), 
    foreign key (ss_id) references ss(id) on update cascade, 
    foreign key (ssa_id) references ssa(id) on update cascade);

Now you don't have the redundant dependency. 现在您没有多余的依赖关系。

It's also not clear that note needs ss_id at all, since it's redundant with the related ssa row. 还不清楚该note ss_id需要ss_id ,因为它与相关的ssa行是多余的。

Try 尝试

DISABLE KEYS 禁用键

or 要么

SET FOREIGN_KEY_CHECKS=0;

make sure to turn it on 确保将其打开

SET FOREIGN_KEY_CHECKS=1;

after. 后。

最终解决问题的是放弃了额外的FK:

alter table note drop foreign key (state_sample_id) references state_sample(id);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM