我有两张桌子:
tree_instance:
- tree_id INT
- country_id INT
- time_segment date
node_instance:
- country_id INT
- time_segment date
- CONSTRAINT `node_instance_ibfk_1` FOREIGN KEY (`time_segment`) REFERENCES `tree_instance` (`time_segment`) ON DELETE NO ACTION ON UPDATE NO ACTION
一些事实:
当我添加新结构时,首先我添加新的tree_instance
,例如
tree_id: 2
country_id: 1
time_segment: 2014-01-01
然后我插入节点。 country_id = 2也是如此。
当我想删除其中一个国家/地区的树时,会出现问题。首先,我尝试删除country_id = 1的所有node_instances。成功。然后我尝试删除tree_instance WHERE country_id = 1,我得到以下错误:
Cannot delete or update a parent row: a foreign key constraint fails (`db_name`.`node_instance`, CONSTRAINT `node_instance_ibfk_1` FOREIGN KEY (`time_segment`) REFERENCES `tree_instance` (`time_segment`) ON DELETE NO ACTION ON UPDATE NO ACTION)
这是因为来自country_id = 2的node_instances指向我要删除的time_segment(约束)。但我无法理解的是,仍然存在一个tree_instance(country_id = 1,我没有删除),其中time_segment可以保存约束。为什么MySQL会抛出约束违规?
答案 0 :(得分:0)
如果我正确理解了这个问题,那么这就是你要做的事情
node_instance
列上的time_segment
(子表)中有一个外键,引用tree_instance.time_segment
node_instance
的{{1}}(子表)中删除记录。此操作成功country_id = 1
删除记录错误的记录。这种情况正在发生,因为外键仍然存在且处于活动状态。它不能让您删除父记录,因为子表中可能有记录,它们仍然引用父表中的记录。要删除父表中的记录,需要禁用约束。
编辑:
我编辑引用正确的外键列。即使foregin键位于tree_instance
列,您也可以删除子表中的记录,但是您将无法从父表中删除记录,因为子表中的外键引用了{{ 1}}父表的列。父表上不允许删除,因为子表中可能有一些记录,它从父表引用值time_segment
答案 1 :(得分:0)
在失败的DELETE FROM tree_instance WHERE country_id = 1
语句之前 - 检查node_instance
是否包含country_id
= 1的行。如果是,则可能尚未提交先前的修改。因此,检查是否存在已存在的交易;当然,如果你使用它们。
答案 2 :(得分:0)
此问题的解决方案是MySQL非唯一约束是特定于MySQL的,如docs中所述:
引用非UNIQUE键的FOREIGN KEY约束不是标准SQL,而是InnoDB扩展。
对非唯一索引的约束可防止删除任何匹配的行。任何。无论是否还有其他记录仍然存在约束。总的答案是,在非唯一字段上使用约束是一个坏主意,简单。