MySQL--索引和事务
一.索引是什么
MySQL的索引是⼀种数据结构,它可以帮助数据库⾼效地查询、更新数据表中的数据。索引通过 ⼀定的规则排列数据表中的记录,使得对表的查询可以通过对索引的搜索来加快速度。
二.索引该用哪个数据结构
1.hash
时间复杂度为O(1),但不支持范围查找,所以不使用
2.二叉搜索树
二叉搜索数中序遍历是一个有序数组,支持范围查找,在最好情况下(完全二叉树)时间复杂度为O(logN),最坏情况下(单分支树)时间复杂度为O(N),无法确保具体的时间复杂度,而每多访问一个节点就会发生一次磁盘I/O,而磁盘I/O跟性能有很大关系,减少I/O次数可以有效的提升性能
3.N插树
继承了二叉搜索树左节点小于根节点,右节点大于根节点的特点,但一个节点有多个值,可以通过设置度的数量来控制一个节点能存储数据的数量,由此可以控制树的高度,时间复杂为O(logN)
4.B+树
是N插树的优化版,是⼀种经常⽤于数据库和⽂件系统等场合的平衡查找树,时间复杂度为O(logN),MySQL索引采⽤的数据结构,以4阶 (度)B+树为例,如下图所示:
三.MySQL中的页
1.页的作用
在 .ibd ⽂件中最重要的结构体就是Page(⻚),⻚是内存与磁盘交互的最⼩单元,默认⼤⼩为 16KB,每次内存与磁盘的交互⾄少读取⼀⻚,所以在磁盘中每个⻚内部的地址都是连续的,之所 以这样做,是因为在使⽤数据的过程中,根据局部性原理,将来要使⽤的数据⼤概率与当前访问的 数据在空间上是临近的,所以⼀次从磁盘中读取⼀⻚的数据放⼊内存中,当下次查询的数据还在这 个⻚中时就可以从内存中直接读取,从⽽减少磁盘I/O提⾼性能
2.页中主要结构
页为存储数据库表中所有类型数据的一个结构,在MySQL中有多种不同类型的⻚,最常⽤的就是⽤来存储数据和索引的"索引⻚",也叫做"数据⻚"
应用:
四.索引分类
聚集索引:
与主键索引是同义词
如果没有为表定义 PRIMARY KEY, InnoDB使⽤第⼀个 UNIQUE 和 NOT NULL 的列作为聚集索引
如果表中没有 ⽤6字节的 PRIMARY KEY 或合适的 UNIQUE NOT NULL 索引,InnoDB会为新插⼊的⾏⽣成⼀个⾏号并 ROW_ID 字段记录, ROW_ID 单调递增,并使ROW_ID作为索引
1.主键索引
当在⼀个表上定义⼀个主键 PRIMARY KEY 时,InnoDB使⽤它作为聚集索引。
非聚集索引:
聚集索引以外的索引称为⾮聚集索引或⼆级索引。
⼆级索引中的每条记录都包含该⾏的主键列,以及⼆级索引指定的列。
InnoDB使⽤这个主键值来搜索聚集索引中的⾏,这个过程称为回表查询
2.普通索引
为了提升査询效率,工作中通常为查询频繁的列创建索引 (列的重复度不高,如性别就不需要),可能为多列创建组合索引,称为复合索引或组全索引
好处:如查询名字时就可以创建普通索引,就会根据名字创建新的索引树,存储的是对应名字的引用和对应行的主键值,根据首字母就很容易找到对应的名字和对应行的主键值,最后进行回表操作,根据主键值就可以快速找到储存数据的值,如果没有普通索引,就找不到关于名字的索引,只能通过全表扫描查询
索引覆盖:如果要找某人的班级,可以以名字和班级创建联合索引,索引类容为名字、班级和主键id,同样的也能找到对应名字的数据行,由于班级就在该索引下,就不用进行回表操作了,可以直接返回真实值,这个过程就叫做索引覆盖
注意:创建索引后,都会创建一个索引树,生成的索引树,也是会占用磁盘空间的,创建索引时,要慎重考虑一下需不需要,索引树越多,对增、删,改的效率影响越大
3.唯一索引
当在⼀个表上定义⼀个唯⼀键 UNQUE 时,⾃动创建唯⼀索引。与普通索引类似,但区别在于唯⼀索引的列不允许有重复值。
五.索引的使用
1.创建索引
2.唯一索引
3.普通索引
4.复合索引
5.该如何看自己的SQL是否走索引
关键字:explain
使用:
type解释
六.事务
1.什么是事务
事务把⼀组SQL语句打包成为⼀个整体,在这组SQL的执⾏过程中,要么全部成功,要么全部失 败(如写入数据,写入一些但没有完全写入就失败就会把刚刚写入的数据撤销)。
2.事务的ACID特性
事务的ACID特性指的是Atomicity (原子性),Consistency (⼀致性), Isolation (隔离性)和Durability (持久性)。
Atomicity (原子性):⼀个事务中的所有操作,要么全部成功,要么全部失败,不会出现只执 ⾏了⼀半的情况,如果事务在执⾏过程中发⽣错误,会回滚( Rollback )到事务开始前的状 态,就像这个事务从来没有执⾏过⼀样;
Consistency (⼀致性):在事务开始之前和事务结束以后,数据库的完整性不会被破坏。如俩人互相转账,转账前俩人钱的总额和转账后俩人钱的总额不变
Isolation (隔离性):数据库允许多个并发事务同时对数据进行读写和修改,隔离性可以防止多 个事务并发执行时由于交叉执行而导致数据的不⼀致。事务可以指定不同的隔离级别,以权衡在不 同的应⽤场景下数据库性能和安全;
Durability (持久性):事务处理结束后,对数据的修改将永久的写入存储介质,即便系统故障 也不会丢失。
3.事务的使用
3.1 事务的开始、提交和回滚
语法:
开始一个新事务:start tansaction 或 begin
提交事务并且对其更改持久化保存: commit
回滚当前事务,取消其更改: rollback
使用:
3.2 事务保存点(savepoint)
作用:在事务的执行过程中设置保存点,回滚时指定的保存点就可以回退到保存点之前的状态
使用:
3.3 手动/自动提交事务
默认情况下,MySQL是⾃动提交事务的,也就是说我们执⾏的每个修改操作,⽐如插⼊、更新和删 除,都会⾃动开启⼀个事务并在语句执⾏完成之后⾃动提交,发⽣异常时⾃动回滚。
语法:
查看是否开启自动提交事务语法和使用:
4.事务的隔离性和隔离级别
4.1 什么是隔离性
MySQL服务可以同时被多个客⼾端访问,每个客⼾端执⾏的DML语句以事务为基本单位,那么不 同的客⼾端在对同⼀张表中的同⼀条数据进⾏修改的时候就可能出现相互影响的情况(重点),为了保证不同 的事务之间在执⾏的过程中不受影响,那么事务之间就需要要相互隔离,这种特性就是隔离性。
4.2 隔离级别
4.3 查看和设置隔离级别
事务的隔离级别分为全局作⽤域和会话作⽤域
查看不同作⽤域事务的隔离级别:
设置事务的隔离级别和访问模式:
语法:
使用方式:
使用:
5.不同隔离级别存在的问题
5.1 READUNCOMMITTED-读未提交与脏读
解释:出现在事务的 READ UNCOMMITTED 隔离级别下,由于在读取数据时不做任何限制,所以并发性 能很⾼,但是会出现⼤量的数据安全问题,⽐如在事务A中执⾏了⼀条 INSERT 语句,在没有执⾏ COMMIT 的情况下,会在事务B中被读取到,此时如果事务A执⾏回滚操作,那么事务B中读取到事务 A写⼊的数据将没有意义,我们把这个理象叫做 " 脏读 "
现象:
5.2 READCOMMITTED-读已提交与不可重复读
解释:为了解决脏读问题,可以把事务的隔离级别设置为 READ COMMITTED ,这时事务只能读到了其 他事务提交之后的数据,但会出现不可重复读的问题,⽐如事务A先对某条数据进⾏了查询,之后事务 B对这条数据进⾏了修改,并且提交( COMMIT )事务,事务A再对这条数据进⾏查询时,得到了事务B 修改之后的结果,这导致了事务A在同⼀个事务中以相同的条件查询得到了不同的值,这个现象要"不 可重复读"。
现象:
5.3 REPEATABLEREAD-可重复读与幻读
解释:每次start transaction 就会记录当前数据库中的一次快照 (旧表),在此事务中无论其他事务怎么修改数据查询(在此隔离级别下select读取的是旧数据)时都是查询该旧表,数据不会改变,这就解决了 ’ 不可重复读 ‘的现象,由于update读取的是最新的数据(保持数据的一致性),在其他事务插入新数据并提交时(必须得提交),该事务更新数据时读取的最新的数据(即其他事务插入数据后的数据),如果修改的是新插入的数据(如果是原表的数据就不会出现幻读),就会在此事务更新新的快照(更改新插入的数据会在该快照中),此时查询就会是新的快照,即会出现新的一行数据,此现象叫做 ’ 幻读 ‘。