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

问题描述 投票:0回答:1

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

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 not null的条目时,一切似乎都能正常工作。但是当我更新/删除具有product_id null的条目时,更改不会级联到sections_t

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

mysql foreign-keys nullable cascade
1个回答
0
投票

您不应该有一个引用可空字段的FK(外键)。这不是标准的SQL和MySQL让你用InnoDB,但tells you not to

对于诸如UPDATE或DELETE CASCADE之类的操作,没有很好地定义对非唯一键或包含NULL值的键的外键引用的处理。建议您使用只引用UNIQUE(或PRIMARY)和NOT NULL的键的外键。

但SQL实际上并不是为了支持带有NULL作为标识符的子行:

您是否理解在默认和通常且通常仅实现(包括在MySQL)模式下的FK匹配是,如果任何FK列为NULL,则无论引用表中的内容是什么,都认为FK约束是否满足? (并且在没有模式下,NULL FK列值与引用表中的任何内容匹配?)因此,即使您使用MySQL功能,也永远不会与表单的FK匹配(x,NULL)?

(你是否理解,在SQL NULL <> NULL的精神下,如果一个带有NULL的FK子行必须在其引用的表中具有相同的值,那么它永远不会,因为引用的表中的任何内容都不能等于该NULL,即使是空值?)

您是否了解没有NULL的UNIQUE索引定义允许表中任何形式的行(p,NULL)? (它在变态的SQL 3VL方式中只是“唯一的”。)那么具有可空列的UNIQUE是否真正捕获了您在引用表中所需的约束?

你是否理解查询会很复杂,因为如果手动想要(x,NULL)对包含的(x,NULL)对,你必须编写像OR id IS NULL这样的东西吗?

如果您需要这些表,则必须为约束和级联编写触发器。但是您应该使用按照SQL期望和支持的方式使用NULL的设计。这仍然可能涉及一些触发器,但您可能会使用一些声明性约束和级联,并且您的设计在SQL使用方面不会是非标准和反直觉的。

© www.soinside.com 2019 - 2024. All rights reserved.