美文网首页
新增唯一索引没有生效,why ?

新增唯一索引没有生效,why ?

作者: Faye小峰 | 来源:发表于2017-12-19 11:47 被阅读0次

场景重现

开发同学为了防止插入多条重复记录,在表中这3个列上加了个唯一性索引: uk_col1_col2_col3 (col1,col2,col3) 。 然而下面这3条数据竟然插入成功了,且没有抛出 ‘Duplicate key’ 的异常:

mysql> insert into uktest(col1,col2,col3) values(1,2,null);
Query OK, 1 row affected (0.01 sec)

mysql> insert into uktest(col1,col2,col3) values(1,2,null);
Query OK, 1 row affected (0.00 sec)

mysql> insert into uktest(col1,col2,col3) values(1,2,null);
Query OK, 1 row affected (0.00 sec)

mysql> select col1,col2,col3  from uktest;
+------+------+------+
| col1 | col2 | col3 |
+------+------+------+
|    1 |    2 | NULL |
|    1 |    2 | NULL |
|    1 |    2 | NULL |
+------+------+------+
3 rows in set (0.00 sec)

上面的三条 SQL 都执行成功了,数据库中插入了多条一样的记录。可按照我们的构想,在执行后两条 SQL 时 应该抛出 ‘Duplicate key’ 的异常的。有点诡异~

还有这种操作

查看表结构如下:

mysql> show create table uktest;
+--------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table  | Create Table                                                                                                                                                                                                                                                                                                                                        |
+--------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| uktest | CREATE TABLE `uktest` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '无意义的ID',
  `col1` int(11) NOT NULL DEFAULT '0',
  `col2` int(11) NOT NULL DEFAULT '0',
  `col3` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_col1_col2_col3` (`col1`,`col2`,`col3`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8     |
+--------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

col1、col2 都是not null 的,插入时有明确的值。col3 列是 datetime 类型,默认值为 NULL

怀疑和 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。

何以解忧?

将 col3 列改为 NOT NULL ,且有默认值。时间默认值可以设置为一个有意义的值,比如'1979-01-01 08:00:01' 或 '2000-01-01 00:00:01'。

这也是为啥军规中明确规定:索引字段请务必设置为 not null 的原因之一啦,除了提高索引效率节省空间外,也是为了避免“唯一索引失效了”这类误会啦~

真相了

[参考]:唯一性约束与null

相关文章

  • 新增唯一索引没有生效,why ?

    场景重现 开发同学为了防止插入多条重复记录,在表中这3个列上加了个唯一性索引: uk_col1_col2_col3...

  • MySQL-对Change Buffer的理解

    Change Buffer的处理过程 对非唯一的普通索引的新增或更新操作,如果索引B+树的需要新增或更新的数据页不...

  • git 中.gitignore文件不生效

    .gitignore文件 新增忽略文件并没有生效 新增的忽略文件没有生效,是因为git是有缓存的,而之前的文件在缓...

  • 两表关联查询字段都有设置索引,但没有生效

    如题,两张表,关联查询的字段都用设置了唯一索引,因为关联查询时LEFT JION,所以左连接的唯一索引不生效我能理...

  • MySQL数据库性能优化

    mysql查询优化: 1.新增字段索引,查询时若使用到or关键字,则两个字段都需建立索引才能生效 2.sql语句包...

  • 7.MySQL优化(2)

    本章要点 1.索引生效2.聚簇索引3.分库分表4.高可用方案 1.索引生效原则 索引生效的情况: 匹配最左前缀 全...

  • 深入理解四种数据库索引类型(- 唯一索引/非唯一索引 - 主键索

    唯一索引/非唯一索引 主键索引(主索引) 聚集索引/非聚集索引 组合索引 唯一索引/非唯一索引 唯一索引 1.唯一...

  • mysql索引

    表结构 联合索引 以下3种情况索引全部生效:说明只要有最左匹配列,索引都能生效,且不受顺序影响,mysql自动优化...

  • MySQL常用索引

    1.主键索引 主键索引必定是唯一索引,且不允许空值 2.唯一索引 除开取值唯一以外,与普通索引没有区别 3.普通索...

  • MySQL减少慢查询的几种方法

    常见索引类型 主键索引它是一种特殊的唯一索引,不允许有空值。 普通索引最基本的索引,它没有任何限制。 唯一索引普通...

网友评论

      本文标题: 新增唯一索引没有生效,why ?

      本文链接:https://www.haomeiwen.com/subject/rvebwxtx.html