媒介
之前做的一个需求,简化形貌下就是接收其他组的 MQ 的音讯,然后在数据库里插进去一条纪录。为了防备他们反复发音讯,插进去多条反复纪录,所以在表中的几个列上加了个唯一性索引。
CREATE UNIQUE INDEX IDX_UN_LOAN_PLAN_APP ON testTable (A, B, C);
这时刻 A,B,C 三列都是不许可 NULL 值的,唯一性束缚也是 work 的。
厥后因为需求的变化,修改了之前的唯一性束缚,又多加了一列。(至于为何加就不赘述了)。
ALTER TABLE testTable DROP INDEX IDX_UN_LOAN_PLAN_APP, ADD UNIQUE KEY `IDX_UN_LOAN_PLAN_APP` (A, B, C, D);
新加的 D 是范例是 datetime, 许可为 NULL,默认值为 NULL。之所以默认值为 NULL,是考虑到不是一切纪录都有这个时刻的, 假如强行设置一个 Magic Value (比方'1970-01-01 08:00:00‘)当作默认值,看起来很新鲜。
蓝后。。。就出题目了。加了 D 以后,唯一性束缚基本就失效了。
Insert into testTable (A,B,C,D) VALUES (1,2,3,NULL); --- OK Insert into testTable (A,B,C,D) VALUES (1,2,3,NULL); --- OK Insert into testTable (A,B,C,D) VALUES (1,2,3,NULL); --- OK
上面的三条 SQL 都是能够实行胜利的,数据库中会有多条一样的纪录。可根据我们之前的设想,在实行后两条 SQL 时 应当抛出 ‘Duplicate key' 的非常的。
厥后查了一下,才发明实在 MySQL 官方文档上已明白说了这一点, 唯一性索引是许可多个 NULL 值的存在的:
A UNIQUE index creates a constraint such that all values in the index must be distinct. An error occurs if you try to add a new row with a key value that matches an existing row. For all engines, a UNIQUE index allows multiple NULL values for columns that can contain NULL.
从下表中也能够看出来不管是采纳什么范例的存储引擎,在竖立 unique key 的时刻都是许可多个 NULL 存在的。。。。
细想一想,实在也蛮合理,毕竟在 MySQL 中以为 NULL 代表着“未知”。 在 SQL 中,任何值与 NULL 的比较返回值都是 NULL 而不是 TRUE, 就算 NULL 与 NULL 的比较也是返回 NULL。
所以只能 fix 了。。。解决办法也蛮简朴粗犷的,直接把线上数据刷了一遍,将“1970-01-01 08:00:00”作为默认值,然后把那列改成不许可为 NULL 的了,咳咳。
MySQL 官网上也有蛮多人讨论过这个题目,一部分人以为这是 MySQL 的 bug, 另一部分则以为是一个 feature,附上链接。
MySQL Bugs: #8173: unique index allows duplicates with null values
相干引荐:
PHP中的范例束缚
MySQL中的束缚与多表查询以及子查询的实例详解
php中范例束缚的思绪代码分享
以上就是MySQL中的唯一性束缚与NULL实例详解的细致内容,更多请关注ki4网别的相干文章!