当前位置: 首页 > 图灵资讯 > java面试题> 金三银四精选java面试题-什么是唯一索引?

金三银四精选java面试题-什么是唯一索引?

来源:图灵教育
时间:2024-01-10 09:57:53
 

什么是唯一索引?

 

讲起来非常简单,其实和 "普通索引"类似,不同的就是:索引列的值必须唯一,但允许有空值。 可以是单列唯一索引,也可以是联合唯一索引。

 

  • 最大的所用就是确保写入数据库的数据是唯一值。

 

什么时候应该使用唯一索引呢?

 

我们前面讲了唯一索引最大的好处就是能保证唯一性。看似没什么太大的价值,可能就会有同学说,我业务层做一个重复检查不就好了。问题就在这个地方,“业务是无法确保唯一性的”,除非你说你的代码没有BUG。很多时候业务场景需要保证唯一性,如果不在数据库加限制的话,总有一天会出现脏数据。

 

那又有同学就说了,既然你不想重复你可以使用主键索引。这个回答也很有意思。

 

  • 我们确实可以通过主键索引来保证唯一,但是,如果你的数据不能保证有序插入。比如说身份证字段,你如果用身份证字段作为主键的话,会导致查询效率降低。
  • 唯一索引还有一个好处就是可以为空,真实的业务场景肯定是可以保证身份证为空的,如果没有绑定身份证就不让注册好像也有点说不过去。

 

聚簇索引的原理就不在这里细讲了,会有一个单独的章节来介绍。

 

唯一索引是否会影响性能呢?

 

我们通过和普通索引来做一个对比,有查询和插入两个场景。

 

 

首先第一个数据查询,一般情况下来说索引是通过B+树从根节点开始层序遍历到叶子结点,数据页内部通过二分搜索。

 

  • 普通索引 查到满足条件的第一条记录,继续查找下一条记录,直到找到不满足条件的记录
  • 唯一索引 查到第一个满足条件的记录,就停止搜索。

 

InnoDB 它是以数据页为单位进行读写的,我们读一条记录,并不是从磁盘加载一条记录,而是以页为单位整体读到内存里面来的。

 

普通索引比唯一索引就多了一次查找和判断下一条记录的操作,也就是一次指针寻找数据和一次计算。当然还有一种特殊情况,读取到的这条数据正好是数据页的最后一条,但是这种概率也是非常低,几乎可以忽略不计。

 

整体看下来看上去性能差距并不大对吧。

 

来看第二个更新的性能,我们按照上面图上的例子在2和6之间插入一个3。

 

在内存中

 

  • 普通索引 找到2和6之间的位置 →插入值结束
  • 唯一索引 找到2和6之间的位置 →当判断有没有冲突插入值结束

 

不在内存中

 

  • 普通索引 将更新记录在change buffer结束
  • 唯一索引 将数据页读入内存→当判断到没有冲突插入值结束

 

数据读取到内存涉及了随机IO访问,这是在数据库里面成本最高的操作之一,而change buffer 就可以减少这种随机磁盘访问,所以性能提示比较明显。所以在这一块来说,如果两者在业务场景下都能满足时可以优先考虑使用普通索引。