当子行使用索引时,是否可以使用外键约束来防止更新父行?
这是父表的架构:
create table if not exists incident_options (
id int not null auto_increment primary key,
idx int not null,
field int not null ,
value varchar(50));
ALTER TABLE `incident_options` ADD unique (`idx`, field);
和子表:
create table if not exists incident_values (
optn int,
value varchar(1000));
ALTER TABLE `incident_values` ADD INDEX (`optn`);
这是我尝试过的约束:
ALTER TABLE `incident_values`
ADD FOREIGN KEY (`optn`) REFERENCES `incident_options`(`id`)
ON DELETE NO ACTION ON UPDATE RESTRICT;
假设我有以下数据:
incident_options
__________________________
|id | idx | field | value |
| 1 | 0 | 1 | foo |
| 2 | 1 | 1 | bar |
--------------------------
incident_values
______________
| optn | value |
| 1 | baz |
--------------
我想要达到的目的是防止' foo'因为该行在incident_values
更新' bar'会没事的
以下是我用来修改行的查询:
insert into incident_options (`idx`,`field`,`value`)
values ('0','1','test')
on duplicate key update
`idx` = values(`idx`),
`field` = values(`field`),
`value` = values(`value`)
目前' foo'将更新为' test'
答案 0 :(得分:1)
问题是您已在错误的表格上设置约束。您已将ON UPDATE RESTRICT
放在incident_values
表上,但当您进行插入和更新时,这一切都发生在incident_options
上。
不幸的是,你不能在incident_options
表中设置这个约束,因为你可能并不总是有一个回到incident_values
表的引用,所以我认为这不可能使用约束。正如Barmar在评论中提到的那样,您可以在更新字段之前以某种方式实施触发器以执行验证。
答案 1 :(得分:1)
有点hackery我实际上实现了我想要的。
强制增加' id'当'价值'已更改,更新了' id'如果有关系,将不被允许
on duplicate key update
idx = values(idx),
field = values(field),
id = if(
values(`value`)=`value`,
id,
(SELECT Auto_increment FROM information_schema.tables WHERE table_name='incident_options')
),
values= values(value)
虽然在我的应用程序中实现它之前,我会看到是否有任何反对使用此解决方案的建议