暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MySQL如何处理唯一索引中的NULL 值?

DBA闲思杂想录 2025-03-11
143

在MySQL中,如果唯一索引的相关字段允许NULL值的话,会出现什么情况?下面构造几个简单的例子,演示一下

mysql> create table test1
    -> (id int, 
    ->  name varchar(16) ,
    ->  unique index udx_test1_n1(name),
    ->  primary key(id)
    -> );
Query OK, 0 rows affected (0.04 sec)


mysql> insert into test1
    -> select 1001, 'k1001';
Query OK, 1 row affected (0.07 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> insert into test1
    -> select 1002, 'k1001';
ERROR 1062 (23000): Duplicate entry 'k1001'for key 'test1.udx_test1_n1'
mysql> 
mysql> insert into test1
    -> select 1003, null;
Query OK, 1 row affected (0.01 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> insert into test1
    -> select 1004, null;
Query OK, 1 row affected (0.01 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> select * from test1;
+------+-------+
| id   | name  |
+------+-------+
| 1003 | NULL  |
| 1004 | NULL  |
| 1001 | k1001 |
+------+-------+
3 rows inset (0.00 sec)

mysql> 

如上测试所示,如果字段name允许为NULL值,而且字段name上建立了唯一索引的话,居然可以插入两条(或多条)name值为NULL的记录,这似乎跟唯一索引的唯一值有点"冲突",接下来我们看看联合唯一索引的情况,如下所示:

mysql> create table test2
    -> (  name1  varchar(12),
    ->    name2  varchar(12),
    ->    uniqueindex udx_test2_n1(name1,name2)
    -> );
Query OK, 0 rows affected (0.06 sec)

mysql> insertinto test2
    -> selectnull'k1';
Query OK, 1 row affected (0.01 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> insertinto test2
    -> selectnull'k1';
Query OK, 1 row affected (0.02 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> select * from test2;
+-------+-------+
| name1 | name2 |
+-------+-------+
| NULL  | k1    |
| NULL  | k1    |
+-------+-------+
2 rows in set (0.00 sec)

mysql> insertinto test2
    -> selectnullnull;
Query OK, 1 row affected (0.00 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> insertinto test2
    -> selectnullnull;
Query OK, 1 row affected (0.01 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> select * from test2;
+-------+-------+
| name1 | name2 |
+-------+-------+
| NULL  | NULL  |
| NULL  | NULL  |
| NULL  | k1    |
| NULL  | k1    |
+-------+-------+
4 rows in set (0.00 sec)

mysql> 

出现这种情况,是因为NULL值的特殊性导致的,如下所示

所以,我们在创建唯一索引时,最好将唯一索引的字段设置为NOT NULL,这样才可以避免唯一索引中出现相同值的记录。

参考资料

  • How are NULL Values in Unique Indexes Handled in MySQL? (Doc ID 1336817.1)


文章转载自DBA闲思杂想录,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论