mysql索引

本文详细解释了InnoDB数据库中的索引类型(聚簇索引、二级索引和联合索引),B+树结构,以及锁的种类(包括悲观锁和乐观锁),重点介绍了多版本并发控制(MVCC)和ReadView在事务隔离中的作用。此外,还涉及了主从复制在读写分离和数据备份中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

索引

聚簇索引

是一种数据存储方式(所有的用户记录都保存在了叶子节点),也就是所谓的数据即索引,索引即数据,“聚簇”是指数据行和相邻的键值聚簇在一起

在这里插入图片描述

优点:

(1)访问速度快:因为聚簇索引是将索引和数据保存在同一个B+树中

(2)对主键的排除查找范围查找速度很快

注意:每个mysql的表只能有一个聚簇索引,一般情况下就是该表的主键

聚簇索引只存在于InnoDB引擎下,只有在搜索条件是主键值时才会发生作用

二级索引

也称为辅助索引、非聚簇索引

同样适用B+树进行存储,但是叶子节点只保存当前二级索引和聚簇索引值,当根据二级索引进行查找数据时,需要先查询到聚簇索引,在根据聚簇索引查询对应的数据,即会经历一次回表操作

联合索引

使用多条表字段进行组合形成一个联合索引,属于非聚簇索引

数据页进行存储数据时,先按照A字段的值进行排序,当A字段的值相同时再根据B字段的值进行排序,在叶子节点上保存A、B和聚簇索引值

B+树索引注意事项

(1)根页面万年不动

1、在第一次存储数据时,开辟一个叶子节点(数据页)空间保存数据

2、当数据足够多需要页分裂的时候,将当前叶子节点进行复制,并将当前叶子节点转换升级成为目录页,复制出的成为新的叶子节点

3、直到最后,初始的叶子节点最终升级为根页面(一直不动)

(2)内节点目录记录的唯一性

1、在二级索引使用中,当内节点二级索引值保持一致时,插入新的数据时不确定数据页地址

2、为了保证新插入记录页能找到对应数据页地址,需要保证B+树的同一层节点内的目录项记录除页号字段以外是唯一的

3、此时二级索引的内节点的目录项记录为索引列的值 + 主键值(聚簇索引值) + 页号

(3)一个页面至少存储两条记录

(1)从数据操作类型划分:

读锁:也叫共享锁,针对同一份数据,允许多个事务的读操作同时进行

写锁:也叫排他锁,当前写操作未执行完的情况下,不允许其他事务进行写操作或者读操作

注意:在InnoDB引擎下,读锁和写锁可以加在表上,也可以加在行上

(2)从数据操作粒度划分:

表锁:在针对某一个表执行例如ALTER TABLE、DROP TABLE等DDL语句时,其他事务对该表执行SELECT、INSERT、UPDATE、DELETE语句时会发生阻塞

其中意向锁属于表锁的一种

1、意向共享锁:SELECT * FROM TABLE …LOCK IN SHARE MODE

2、意向排他锁:SELECT * FROM TABLE …FOR UPDATE

意向锁是存储引擎自己维护的,用户无法手动操作意向锁,在未数据添加共享/排他锁之前,InnoDB会先获取数据行所在表的对应意向锁

行锁:将表中一条记录锁上

当事务获取到共享锁时,其他事务也能获取共享锁,但不能获取排他锁

当食物获取到排他锁时,其他事务既不能获取共享锁,也不能获取排他锁

页锁:针对每一个数据页(包含多条激励)进行加锁,并发度一般,可能会出现死锁

(3)从对待锁的态度划分:

悲观锁:共享资源每次只给一个线程事务使用,其他线程阻塞,用完后再把资源转让给其他线程(如同Java中的Synchronized和ReentrantLock)

乐观锁:不采用数据库的锁机制,一般通过版本号机制CAS机制来实现。乐观锁适用于多读的应用类型,提高吞吐量

隐藏字段、Undo Log版本链

在InnoDB存储引擎中,聚簇索引记录中存在两个必要的隐藏项:

(1)trx_id:每次一个事务对某条聚簇索引记录进行改动时,都是记录上该事务的事务id

(2)roll_pointer:每次对聚簇索引记录进行改动时,都会把旧版本写入到undo日志中,这个隐藏列相当于一个指针,可以通过它来找到记录修改前的信息
在这里插入图片描述

在这里插入图片描述

多版本并发控制MVCC

MVCC是通过数据行的多个版本管理来实现数据库的并发控制,提供在InnoDB事务隔离级别下执行一致性读操作的保证

为了查询一些正在被另一个事务更新的行,并且可以看到它们被更新之前的值,这样在做查询的时候就不用等待另一个事务释放锁

MVCC实现依赖:隐藏字段、Undo Log、Read View

Read View

假如另一个事务已经修改了记录但未提交,是不能直接读取最新版本的记录的,核心问题是需要判断一下版本链中哪个版本是当前事务可见的,这就是Read View要解决的问题

重要内容:

(1)creator_trx_id:创建这个Read View的当前事务id

只有在对表中的记录做改动时(执行insert、update、delete等语句)才会为事务分配id

(2)trx_ids:表示生成Read View时当前系统中活跃的读写事务的事务id列表

(3)up_limit_id:活跃的事务中最小的事务ID

(4)low_limit_id:表示生成Read View时系统应该分配给下一个事务的事务id值

在访问某条记录时,只需要按照规则判定记录的某个版本是否可见,规则如下

(1)若被访问版本事务ID(trx_id)值与Read View中的creator_trx_id值相同,说明当前事务在访问自己修改过的记录,则允许访问

(2)若被访问版本事务ID(trx_id)值小于Read View中的up_limit_id值,说明生成该版本的事务在当前事务生成Read View前已经提交,则允许访问

(3)若被访问版本事务ID(trx_id)值大于等于Read View中的low_limit_id值,说明生成该版本的事务在当前事务生成Read View后才开启,则不允许访问

(4)若被访问版本事务ID(trx_id)值在Read View的up_limit_id和low_limit_up值之间,则需要判断事务ID(trx_id)是否在活跃事务id列表(trx_ids)中

若存在trx_ids中,说明创建Read View时生成该版本的事务还是活跃的,则该版本不允许被访问

若不存在trx_ids中,说明创建Read View时生成该版本的事务已经被提交,则该版本允许被访问

整体操作流程:

(1)首先获取事务自己的版本号,也就是事务ID

(2)获取Read View

(3)查询得到的数据,然后与Read View中的事务版本号进行比较

(4)如果不符合Read View规则,就需要从Undo Log中获取历史快照

(5)最后返回符合规则的数据

注意事项:

(1)在隔离级别为读已提交(READ COMMITTED)时,每次读取数据前都生成一个Read View

(2)在隔离级别未可重复读(REPEATABLE READ)时,只会在第一次读取数据时生成一个Read View,之后的查询都继续复用该Read View

主从复制

在这里插入图片描述

主从复制的作用:读写分离、数据备份、高可用

原理:Slave会从Master读取binlog来进行数据同步

在这里插入图片描述

在这里插入图片描述

主从同步数据要保持读库和写库的数据一致(最终一致性)

写数据必须到写库,读数据不一定到读库

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值