Mysql 具有可空列的唯一约束

Mysql 具有可空列的唯一约束,mysql,innodb,Mysql,Innodb,我有一个包含嵌套类别的表。我希望避免在相同级别的项目上出现重复的名称(即,具有相同父级的类别)。我带来了这个: CREATE TABLE `category` ( `category_id` int(10) unsigned NOT NULL AUTO_INCREMENT, `category_name` varchar(100) NOT NULL, `parent_id` int(10) unsigned DEFAULT NULL, PRIMARY KEY (`category

我有一个包含嵌套类别的表。我希望避免在相同级别的项目上出现重复的名称(即,具有相同父级的类别)。我带来了这个:

CREATE TABLE `category` (
  `category_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `category_name` varchar(100) NOT NULL,
  `parent_id` int(10) unsigned DEFAULT NULL,
  PRIMARY KEY (`category_id`),
  UNIQUE KEY `category_name_UNIQUE` (`category_name`,`parent_id`),
  KEY `fk_category_category1` (`parent_id`,`category_id`),
  CONSTRAINT `fk_category_category1` FOREIGN KEY (`parent_id`) REFERENCES `category` (`category_id`) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_spanish_ci

不幸的是,
category\u name\u UNIQUE
没有对根级别的类别(那些
parent\u id
为空的类别)强制执行我的规则。是否有合理的解决办法?

合理的解决办法可能包括

  • 如果更新/插入操作对速度不重要,则使用触发器检查约束
  • 使用某种特殊值来表示null;这可以相对正确地建模-有一个id为0的根节点,它将永远不会被删除,父节点id默认为0,并且在删除时设置默认值

据我所知,在数据库端强制执行的可能性:

  • 定义“根”节点,只允许添加到根节点,而不是“新”根节点,或
  • 添加更新之前Trirger的插入之前

  • 顺便说一句:在父项上删除类别提升为根类别,这是您想要的吗?

    «在父项上删除类别提升为根类别,这是您想要的吗?»-简短回答,是的。随着开发的进行,我可能会修改它,但如果我想让MySQL为我处理它,我想我需要编写一个触发器。我想我只允许在根级别进行重复。不管怎样,这简化了删除代码。在MySQL中,恐怕没有关于DELETE SET DEFAULT的
    ,(啊,的确……被解析器识别,但被拒绝了):“SET DEFAULT:这个动作被解析器识别,但InnoDB拒绝包含ON DELETE SET DEFAULT或ON UPDATE SET DEFAULT子句的表定义。”好的,您可以在触发器中实现级联。MySQL中的触发器不允许更改受影响表中的其他行。根据,我看到,但是有两件事需要尝试(没有尝试任何)-1)使用0作为根:您不需要更新其他行,只需更新当前行,使用ON DELETE SET NULL创建一个触发器,该触发器将检查NULL并将其转换为0(2)使用NULL作为根:创建一个触发器,该触发器将检查(NULL,category_id)的唯一性,仅当parent_id为NULL时运行它(以避免破坏所有其他行的性能),并且您不需要更新任何内容-如果(NULL,category_id),只需导致触发器失败已经存在。