我创建了独特的复合指数:
Alter Table TableX Add Unique Index `UniqueRecord` (A,B,C,D)
问题是有时C
可能为NULL。
我注意到了
`Insert IGNORE`
在某些情况下仍然会添加重复记录,结果是这些传入记录的C
为NULL。
我通过以下方式测试了这个问题的假设:
Select concat(A,B,C,D) as Index from TableA where C is NULL
并且每个案例中的Index
实际上都是NULL。从select:
Select concat(A,B,D) as Index from TableA where C is NULL
我得到了预期的字符串值vs nulls。
所以问题是,除了像set C='' where C is NULL
之类的更新之外,是否有某种方法可以设置索引以使其有效?我不愿意简单地创建索引A,B,D
,因为当C
实际上不是NULL时,可能会引入不需要的欺骗。
更新:
我确实在创建索引时尝试使用IfNull
但是Mysql不喜欢这样:
Alter Table TableA Add Unique Index UniqueLocator (A,B,IfNull(C,''),D
Mysql说:
[Err] 1064 - You have an error in your SQL syntax;
check the manual that corresponds to your MySQL server version
for the right syntax to use near 'C,''),D)' at line 1
答案 0 :(得分:0)
是MySQL允许在唯一索引中使用NULL,这是正确的做法。但是,如果你不喜欢,你可以将C列定义为NOT NULL。
答案 1 :(得分:0)
MySQL - 但不是所有数据库 - 允许唯一索引中的重复NULL
值。我认为ANSI标准在这一点上是相当模糊的(或者甚至可能是矛盾的)。你基本上有两个选择。
第一种是为列定义默认值。这在代码方面可能不具吸引力,但它至少会在重复插入时产生错误。例如,如果“C”是对自动递增的id的外键引用,那么您可以使用-1
或0
作为默认值。如果是日期,您可以使用零日期。
另一个解决方案是触发器,您可以在执行插入(或更新)之前手动检查重复值。