为什么唯一索引能保证数据唯一?

为什么唯一索引能保证数据唯一?

首先,mysql作为一个数据库,内部主要分为两层,一层是server层,一层是存储引擎层(一般是innodb)。
server层主要管的是数据库链接,权限校验,以及sql语句校验和优化之类的工作。请求打到存储引擎层,才是真正的查询和更新数据的操作。
大家都知道数据库是持久化存储,且最后都是把数据存到磁盘上的。

那数据库读写是直接读写磁盘数据吗?

不是,如果直接读写磁盘的话,那就太慢了,为了提升速度。
它在磁盘前面加了一层内存,叫buffer pool。它里面有很多细节,但最主要的就是个双向链表,里面放的是一个个数据页,每个数据页的大小默认是 16kb,数据页里面放的就是磁盘的数据。

在这里插入图片描述

于是有了这层buffer pool内存,mysql的读和写操作都可以先操作这部分内存,如果想要读写的数据页不在buffer pool里,再跑到磁盘里去捞。由于读写内存的速度比读写磁盘快得多。

所以引擎读写都快多了。

但这还不够,很多时候写操作,我的诉求就是把xx更新为xx,或插入xx,数据库光知道这一点就够了,我根本不需要知道数据页原来长什么样子。

有点抽象?举个例子吧。

比方说我想要把id=1的这条数据的phone_no字段更新为100,数据库知道这一点就够了,至于这条数据原来phone_no究竟是等于20,还是30,这根本不重要,反正最后都会变成我想要的phone_no=100。

也就是说,如果有那么一块内存,记录下我准备把数据改成什么样子,然后后续异步慢慢更新到磁盘数据上。那我甚至到不需要在一开始就把这块数据从磁盘读到buffer pool中,按照这个思路,change buffer就来了。

在这里插入图片描述

于是乎,写加了普通索引的数据,它只要把想要写的内容写到change buffer上,就立马结束返回了。后面innodb引擎拿着这个change buffer,再异步读入磁盘数据到内存,将change buffer的数据修改到数据页中,再写回磁盘,这速度就上来了,秒啊。

但这个change buffer,放在唯一索引这里就不管用了,毕竟,它得保证数据真的只有一条,那就得去看下数据库里,是不是真的有这条数据。

所以,对于insert场景,普通索引把需求扔到change buffer就完事返回了,而唯一索引需要真的把数据从磁盘读到内存来,看下是不是有重复的,没重复的再插入数据。

这唯一索引,在性能上就输了一截了。

所以回到唯一索引为什么能保证数据唯一的问题上,一句话概括就是,唯一索引会绕过change buffer,确保把磁盘数据读到内存后再判断数据是否存在,不存在才能插入数据,否则报错,以此来保证数据是唯一的。

总结

加唯一索引可以保证数据并发写入时数据唯一,而且最省事省心。
数据库通过引入一层buffer pool内存来提升读写速度,普通索引可以利用change buffer提高数据插入的性能。
唯一索引会绕过change buffer,确保把磁盘数据读到内存后再判断数据是否存在,不存在才能插入数据,否则报错,以此来保证数据是唯一的。
更改隔离级别为串行化,也能实现并发写入时数据唯一。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值