MySQL:不尊重"null"值的唯一索引

PLM*_*M57 1 mysql constraints

null在MySQL v5.6.20中创建一个尊重值的唯一索引时遇到了问题.我在这里查了类似的答案.但无法解决我的问题.

期望的行为

我想要一个引用另外三个table(date_list_assignment)的表.该表的目的是将date_list条目映射到课程类别和/或date_list类别.因此,第一列是强制性的,而后两列则不是.如果后两个是null日期列表,则条目被声明为全局.如果日期列表条目在此表中没有条目,则它不会显示在任何位置.

以下是条目的一些示例及其含义:

# entry which is global within course category 2
date_list_id: 1, course_category_id: 2, date_list_category_id: null

# entry which is global
date_list_id: 1, course_category_id: null, date_list_category_id: null

# entry which is only visible within course category 2 and date list category 17
date_list_id: 1, course_category_id: 2, date_list_category_id: 17
Run Code Online (Sandbox Code Playgroud)

简短版本:我想确保三列中的任何组合在表中保持唯一...无论值是否为空.

表模式

我有下表:

CREATE TABLE `date_list_assignment` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `date_list_id` int(11) NOT NULL,
  `course_category_id` int(11) DEFAULT NULL,
  `date_list_category_id` int(11) DEFAULT NULL,
  `created` int(11) DEFAULT NULL,
  `created_by` int(11) DEFAULT NULL,
  `updated` int(11) DEFAULT NULL,
  `updated_by` int(11) DEFAULT NULL,

  PRIMARY KEY (`id`),
  UNIQUE KEY `IN_relation_unique` (`date_list_id`,`course_category_id`,`date_list_category_id`),

  KEY `FK_date_list_assignment_user_created` (`created_by`),
  KEY `FK_date_list_assignment_user_updated` (`updated_by`),
  KEY `FK_date_list_assignment_course_category` (`course_category_id`),
  KEY `FK_date_list_assignment_date_list_category` (`date_list_category_id`),

  CONSTRAINT `FK_date_list_assignment_course_category` FOREIGN KEY (`course_category_id`) REFERENCES `course_category` (`id`) ON DELETE SET NULL ON UPDATE CASCADE,
  CONSTRAINT `FK_date_list_assignment_date_list` FOREIGN KEY (`date_list_id`) REFERENCES `date_list` (`id`) ON UPDATE CASCADE,
  CONSTRAINT `FK_date_list_assignment_date_list_category` FOREIGN KEY (`date_list_category_id`) REFERENCES `date_list_category` (`id`) ON DELETE SET NULL ON UPDATE CASCADE,
  CONSTRAINT `FK_date_list_assignment_user_created` FOREIGN KEY (`created_by`) REFERENCES `user` (`id`) ON DELETE SET NULL ON UPDATE CASCADE,
  CONSTRAINT `FK_date_list_assignment_user_updated` FOREIGN KEY (`updated_by`) REFERENCES `user` (`id`) ON DELETE SET NULL ON UPDATE CASCADE

) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Run Code Online (Sandbox Code Playgroud)

问题

如您所见,我IN_relation_unique在三列上声明了一个唯一的索引().但是,我仍然可以创建具有例如这些值的相同行:

date_list_id: 1, course_category_id: 2, date_list_category_id: null
Run Code Online (Sandbox Code Playgroud)

我知道当前MySQL版本中的一些行为发生了变化,这也是我使用索引而不是允许空值的复合PK的原因.

例如,这个答案表明,这是MySQL中的预期行为.如果是这样,你怎么能实现这一点,因为复合PK也不再允许空值!

谢谢你的帮助!

Pre*_*red 6

是的,这是MySQL中的预期行为(实际上也是ANSI-92).NULL在唯一键中,值不会被视为相等的值,并且主键不能NULL按定义包含值.

当且仅当表中没有两行在唯一列中具有相同的非空值时,才满足唯一约束.此外,如果使用PRIMARY KEY定义唯一约束,则它要求指定列或列中的任何值都不是空值.

(http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt)

既然你对空列的外键约束,我会建议一个虚拟值添加到它规定的事实,父母是不相关的或者没有确定父表(该记录,其中ID = 0也许)和添加NOT NULL约束专栏.(另外,您可以添加虚拟值DEFAULT).