首页 > 图灵资讯 > java面试题>正文
金三银四精选java面试题-什么是唯一索引?
2024-01-10 09:57:53
什么是唯一索引?
讲起来非常简单,其实和 "普通索引"类似,不同的就是:索引列的值必须唯一,但允许有空值。 可以是单列唯一索引,也可以是联合唯一索引。
- 最大的所用就是确保写入数据库的数据是唯一值。
什么时候应该使用唯一索引呢?
我们前面讲了唯一索引最大的好处就是能保证唯一性。看似没什么太大的价值,可能就会有同学说,我业务层做一个重复检查不就好了。问题就在这个地方,“业务是无法确保唯一性的”,除非你说你的代码没有BUG。很多时候业务场景需要保证唯一性,如果不在数据库加限制的话,总有一天会出现脏数据。
那又有同学就说了,既然你不想重复你可以使用主键索引。这个回答也很有意思。
- 我们确实可以通过主键索引来保证唯一,但是,如果你的数据不能保证有序插入。比如说身份证字段,你如果用身份证字段作为主键的话,会导致查询效率降低。
- 唯一索引还有一个好处就是可以为空,真实的业务场景肯定是可以保证身份证为空的,如果没有绑定身份证就不让注册好像也有点说不过去。
聚簇索引的原理就不在这里细讲了,会有一个单独的章节来介绍。
唯一索引是否会影响性能呢?
我们通过和普通索引来做一个对比,有查询和插入两个场景。
首先第一个数据查询,一般情况下来说索引是通过B+树
从根节点开始层序遍历到叶子结点,数据页内部通过二分搜索。
- 普通索引 查到满足条件的第一条记录,继续查找下一条记录,直到找到不满足条件的记录
- 唯一索引 查到第一个满足条件的记录,就停止搜索。
InnoDB
它是以数据页为单位进行读写的,我们读一条记录,并不是从磁盘加载一条记录,而是以页为单位整体读到内存里面来的。
普通索引比唯一索引就多了一次查找和判断下一条
记录的操作,也就是一次指针寻找数据和一次计算。当然还有一种特殊情况,读取到的这条数据正好是数据页的最后一条,但是这种概率也是非常低,几乎可以忽略不计。
整体看下来看上去性能差距并不大对吧。
来看第二个更新的性能,我们按照上面图上的例子在2和6之间插入一个3。
在内存中
- 普通索引 找到2和6之间的位置 →
插入值
→结束
- 唯一索引 找到2和6之间的位置 →
当判断有没有冲突
→插入值
→结束
不在内存中
- 普通索引 将更新记录在
change buffer
→结束
- 唯一索引 将数据页读入内存→
当判断到没有冲突
→插入值
→结束
数据读取到内存涉及了随机IO访问,这是在数据库里面成本最高的操作之一,而change buffer
就可以减少这种随机磁盘访问,所以性能提示比较明显。所以在这一块来说,如果两者在业务场景下都能满足时可以优先考虑使用普通索引。