MySQL中的唯一性约束与NULL详解

发布时间 - 2026-01-11 01:11:47    点击率:

前言

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

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持。


# mysql  # 唯一约束  # null  # 详解MySQL中的外键约束问题  # MySQL约束类型及举例介绍  # MySQL外键约束的禁用与启用命令  # MySQL约束超详解  # mysql增加外键约束具体方法  # Mysql中的事务是什么如何使用  # MySql的事务使用与示例详解  # mysql实现事务的提交和回滚实例  # 全面了解MySql中的事务  # MySQL约束和事务知识点详细归纳  # 都是  # 多个  # 多条  # 值为  # 默认值  # 是一个  # 这是  # 几个  # 都有  # 也有  # 会有  # 就不  # 说了  # 这个问题  # 一遍  # 才发现  # 线上  # 考虑到  # 两条  # 咳咳 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 头像制作网站在线观看,除了站酷,还有哪些比较好的设计网站?  Python函数文档自动校验_规范解析【教程】  Laravel怎么多语言本地化设置_Laravel语言包翻译与Locale动态切换【手册】  哪家制作企业网站好,开办像阿里巴巴那样的网络公司和网站要怎么做?  Laravel Eloquent访问器与修改器是什么_Laravel Accessors & Mutators数据处理技巧  个人网站制作流程图片大全,个人网站如何注销?  如何在橙子建站中快速调整背景颜色?  如何快速辨别茅台真假?关键步骤解析  如何快速搭建个人网站并优化SEO?  如何用狗爹虚拟主机快速搭建网站?  如何用虚拟主机快速搭建网站?详细步骤解析  Laravel如何使用Blade模板引擎?(完整语法和示例)  DeepSeek是免费使用的吗 DeepSeek收费模式与Pro版本功能详解  制作无缝贴图网站有哪些,3dmax无缝贴图怎么调?  如何破解联通资金短缺导致的基站建设难题?  Laravel怎么返回JSON格式数据_Laravel API资源Response响应格式化【技巧】  网站建设保证美观性,需要考虑的几点问题!  浅谈javascript alert和confirm的美化  Laravel如何使用软删除(Soft Deletes)功能_Eloquent软删除与数据恢复方法  JavaScript 输出显示内容(document.write、alert、innerHTML、console.log)  *服务器网站为何频现安全漏洞?  西安市网站制作公司,哪个相亲网站比较好?西安比较好的相亲网站?  如何在云虚拟主机上快速搭建个人网站?  如何在HTML表单中获取用户输入并用JavaScript动态控制复利计算循环  php中::能调用final静态方法吗_final修饰静态方法调用规则【解答】  Midjourney怎样加参数调细节_Midjourney参数调整技巧【指南】  Bootstrap整体框架之CSS12栅格系统  Laravel如何实现本地化和多语言支持?(i18n教程)  php后缀怎么变mp4格式错误_修改扩展名提示格式不对怎么办【技巧】  长沙企业网站制作哪家好,长沙水业集团官方网站?  HTML5空格在Angular项目里怎么处理_Angular中空格的渲染问题【详解】  打造顶配客厅影院,这份100寸电视推荐名单请查收  如何在阿里云购买域名并搭建网站?  Laravel怎么调用外部API_Laravel Http Client客户端使用  Laravel N+1查询问题如何解决_Eloquent预加载(Eager Loading)优化数据库查询  原生JS获取元素集合的子元素宽度实例  如何获取免费开源的自助建站系统源码?  Laravel的HTTP客户端怎么用_Laravel HTTP Client发起API请求教程  Laravel如何实现登录错误次数限制_Laravel自带LoginThrottles限流配置【方法】  Laravel如何使用Service Provider注册服务_Laravel服务提供者配置与加载  高性能网站服务器配置指南:安全稳定与高效建站核心方案  Google浏览器为什么这么卡 Google浏览器提速优化设置步骤【方法】  Laravel怎么清理缓存_Laravel optimize clear命令详解  如何在腾讯云服务器上快速搭建个人网站?  Laravel如何创建自定义Facades?(详细步骤)  如何在VPS电脑上快速搭建网站?  Win11怎么修改DNS服务器 Win11设置DNS加速网络【指南】  微博html5版本怎么弄发语音微博_语音录制入口及时长限制操作【教程】  Laravel怎么设置路由分组Prefix_Laravel多级路由嵌套与命名空间隔离【步骤】  jQuery中的100个技巧汇总