更新/删除空字段时Mysql级联

时间:2018-03-03 15:04:12

标签: mysql foreign-keys nullable cascade

我有一个包含两个字段的表,一个可空,一个不可空。这些字段构成此表中的复合唯一键

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

如何级联包含空字段的条目的更改?

1 个答案:

答案 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使用方面反直觉。