问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

MySQL数据库实战教程-52-唯一性约束

发布网友 发布时间:2022-04-13 03:28

我来回答

1个回答

懂视网 时间:2022-04-13 03:56

这里记录的是很久之前的一个 bug 了,主要给大家介绍了关于MySQL中唯一性约束与NULL的相关资料,文中介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友们下面来一起看看吧。

前言

之前做的一个需求,简化描述下就是接受其他组的 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

总结

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
笔记本电脑的哪些牌子什么牌子的笔记本电脑好 笔记本电脑品牌质量排行榜你知道哪个最耐用全面解析笔记本电脑品牌的质 ... 十大笔记本电脑品牌笔记本电脑推荐品牌 各大汽车电脑品牌厂家官方售后服务电话合辑v3.00 哪种笔记本电脑售后好哪个品牌电脑售后好 各大笔记本电脑品牌售后网点及售后电话汇总解决您笔记本电脑问题的选 ... 如何教育孩子成学霸 学霸的家长是怎样培养孩子的? 聪明的懒孩子怎么变成学霸 学霸孩子怎么培养 为什么左耳朵里好像有个东西一直在撞。咚咚咚…过一会儿叫几声…会不会发言了? 耳朵里面长了个包有时听不到声音但用手按一下它就好两分钟这是为什么 为什么我的耳朵里面长了一个包,有点化脓,一直没发 耳朵里有个疙瘩,怎么办,那个疙瘩连得血管了 不知道为什么,耳朵里长了一个疙瘩,小小的,很硬,一插活塞耳机就很疼,原本只长一边的,现在另一只耳朵 为什么我耳朵里一个个圆圆的东西,自己挖耳屎时,一碰还可以滚动,还有时候我用力洒鼻涕,突然耳朵像堵塞 外耳道里有个软软的包 耳朵里有个硬硬的东西,掏耳朵的 为什么耳朵里面有时候会长一颗鼓鼓的东西。一动到就会很痛的。 耳朵里有个疙瘩不捏不疼为什么 为什么耳朵里面有两个洞? 为什么耳朵里有个东西一直跑来跑去? 为什么耳朵里有一颗东西在动 线性标注适合什么场合 数据库什么是唯一约束和约束的区别 删除微信好友不记得怎么加回来? 把好友删除 没有 只有转账记录 怎么加回来 删掉了微信好友,但是又不知道和手机号,怎么加回? 怎样在Word表示某个区间,如1到10的范围。1到10之间插入1个符号。 牙龈发炎好疼,有什么办法先止痛 快手上的游戏栏怎么让它消失? 快手个人主页面上有个游戏王者的标怎么取消? 什么是主键约束什么是唯一性约束两者有什么区别 删掉了微信好友,但是又不知道和手机号,怎么加回? 把好友删除 没有 只有转账记录 怎么加回来 删除微信好友不记得怎么加回来? 大蒜种植对土壤有什么要求? 大蒜要求怎样的土壤营养条件? 大蒜栽培的土壤耕作要求如何? 大蒜适宜酸性土还是碱性土壤 大蒜产地,什么样的土壤能种大蒜,大个蒜怎么种? 淡水热带鱼观赏鱼有哪些种类 鱼的种类有多少种 温带鱼是什么鱼?有哪些种类?请发些温带鱼的图片。 淡水热带鱼种类有哪些 怎样养淡水热带鱼? 没钱交房租,上海男子欲*送外卖,疫情给人们的生活带来了哪些影响? 因疫情拖欠房租半年了被房东起诉怎么办? 因疫情交不起房租,裁员又导致员工递交劳动仲裁怎么办? 没钱付房租,房东还不同意提前终止合同,给房东打了欠条,但还是扣留我的设备和物品,我该怎么办?