我有一个包含两个字段的表,一个可空,一个不可空。这些字段构成此表中的复合唯一键
CREATE TABLE `sections` (
`product_id` varchar(255) NULL DEFAULT NULL,
`id` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `sections`
ADD UNIQUE KEY (`product_id`, `id`);
我有另一个表,在第一个表的唯一键字段上有外键约束
CREATE TABLE `sections_t` (
`product_id` varchar(255) NULL DEFAULT NULL,
`section_id` varchar(255) NOT NULL,
`name` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `sections_t`
ADD CONSTRAINT `sections_t_ibfk_1` FOREIGN KEY (`product_id`, `section_id`) REFERENCES `sections` (`product_id`, `id`) ON DELETE CASCADE ON UPDATE CASCADE;
当我更新/删除sections
表上product_id
非{null}的条目时,一切似乎都能正常工作。但是当我更新/删除product_id
null的条目时,更改不会级联到sections_t
。
如何级联包含空字段的条目的更改?
答案 0 :(得分:0)
您不应该使用引用可空字段的FK(外键)。它不是标准的SQL& MySQL允许你使用InnoDB但tells you not to:
对于诸如UPDATE或DELETE CASCADE之类的操作,没有很好地定义对非唯一键或包含NULL值的键的外键引用的处理。建议您使用只引用UNIQUE(或PRIMARY)和NOT NULL的键的外键。
但SQL实际上并不是为了支持带有NULL作为标识符的子行:
你明白FK匹配默认&平常&通常只实现(包括在MySQL中)模式是如果任何FK列为NULL,那么无论引用表中的内容是什么,FK约束都被认为是满足的? (并且在没有模式下,NULL FK列值与引用表中的任何内容匹配?)因此,即使您使用MySQL功能,也永远不会与表单的FK匹配(x,NULL)?
(你是否明白,如果一个带有NULL的FK子行必须在其引用的表中具有相等的SQL NULL<> NULL的精神,那么它永远不会,因为引用表中的任何内容都不能等于无论如何,NULL,甚至是NULL?)
您是否了解不带NULL的UNIQUE索引定义允许表中任何形式的行(p,NULL)? (它只是"唯一的"在变态的SQL 3VL方式中。)所以具有可空列的UNIQUE真正捕获了你想要的引用中的约束表
您是否理解查询会很复杂,因为如果您手动想要(x,NULL)对(x,非NULL)对包含,您必须编写OR id IS NULL这样的东西吗?
如果你想要那些表,你将不得不为约束和&级联。但是你应该使用一种使用NULL的设计,就像SQL期望的那样。支持。这仍然可能涉及一些触发器,但您可能会使用一些声明性约束&级联&你的设计不会成为非标准的&在SQL使用方面反直觉。