首先唯一约束和唯一索引是两个概念,千万不要混淆。
唯一约束:保证在一个字段或者一组字段里的数据都与表中其它行的对应数据不同。可插入null,并且可以插入多个null。
唯一索引:不允许具有索引值相同的行,从而禁止重复的索引或键值。也可插入null。
关于唯一索引可插入多个null值的实验:
create table test3(
id int PRIMARY KEY,
name VARCHAR(10)
)
create UNIQUE INDEX inx_unique_name on test3(name);
insert into test3 values(1,'a');
insert into test3 values(2,'z');
insert into test3 values(3,'q');
insert into test3 values(4,'t');
insert into test3 values(5,NULL);
insert into test3 values(8,NULL);
insert into test3 values(6,'y');
insert into test3 values(7,'u');
explain select * from test3 where name is null;
实验结果证明:查询字段为null的列,用到了索引。
疑惑:既然唯一索引要求索引值不相同,那为什么可以插入多个null,null不也相同吗?
其实我们可以这么理解,在mysql中 null != null
冷知识1:在mysql中null是最小的,也就是说在二级索引中,null排在叶子节点最前面,并且默认null!=null。
冷知识2:在mysql中存在非叶子节点的关键字有很多相同,这怎么区分呢,就好比一个表的某个字段很多数据相同(当然这样的列不适合建索引),假设它建了索引,那么会造成很多非叶子节点关键字相同,为了区分,InnoDB在非叶子节点上加入了第三个值主键值,也就是说非叶子节点:该列索引值+主键值+页码(指针)
区别(mysql中):
- 约束是为了保证数据的完整性,索引是为了辅助查询;
- 创建唯一约束时,会自动的创建唯一索引;————MySQL 中唯一约束是通过唯一索引实现的,为了保证没有重复值,在插入新记录时会再检索一遍,怎样检索快,当然是建索引了,所以,在创建唯一约束的时候就创建了唯一索引。
- 理论上不一样,在实际使用时,基本没有区别。
注意:
可以在把唯一约束的列作为外键,但是如果该列只有唯一索引没有约束,理论上作为外键就会报错。
但是在mysql中做实验,该列只有唯一索引,作为外键是不报错的。——这也是与oracle不同的地方。可做实验。
下面将写《MySQL是怎样运行的:从根儿上理解MySQL》(小孩子)的阅读笔记,感兴趣的可以关注一下。