本文仅用作本人的笔记管理。
索引模块
主要记录和索引相关的笔记
为什么要使用索引
避免全表扫描,字典。大幅提升查询数据。
优点:
- 快速查询数据
什么样的信息能成为索引
- 主键、唯一键以及普通键
索引的数据结构
常用的数据结构有:
- 生成索引,简历二叉查找树进行二分查找
- 生成索引,建立B-Tree结构进行查找
- 生成索引,建立B±Tree结构进行查找
- 生成索引,建立Hash结构进行查找
数据库事务的四大特性
数据库事务的四大特性可以简单地用四个字母表示:ACID。
-
A 原子性(Atomic) 表示事务包含的所有操作,要么全部执行,要么失败就全部回滚。
-
C 一致性(Consistency) 表示数据库是从一个一致的状态转向另一个一致的状态,满足完整性约束。比如A和B两人加起来一共有两千块。那么无论A向B转账或者B向A转账多少钱,他们加起来的一共也永远只有两千块。
-
I 隔离性(Isolation) 多个事务并发执行的时候,一个事务的执行并不会影响其他事务的执行。
-
D 持久性(Durability) 表示一个事务一旦提交,其修改就会永久地保存在数据库中。DBMS要求事务一旦提交,就要提供一定的冗余。比如MySQL就会把所有的操作都写入一个表,以便发生错误时时可以恢复。
事务隔离级别以及各级别下的并发访问问题
并发访问可能引起的问题
更新丢失
MySQL各级别的隔离级别在数据库层面均可避免。主要关注程序方面。
脏读
脏读指的是一个事务读到另一个事物的未更新数据。该问题可以在READ-COMMITED事务隔离级别以上可避免。
不可重复读
事务A多次读取统一数据,而在事务A读取的过程中,事务B对该数据进行了修改,从而使得事务A多次读到的数据不一致。
在REPEATABLE-READ事务隔离级别以上可避免。
幻读
事务A多次读取统一数据,而在事务A读取的过程中,事务B对该表新增或删减列,从而使得事务A多次读到的数据列不一致。
SERIALIZABLE事务隔离级别可以避免。
如图:
事务隔离级别越高,安全性越高,串行化执行越严重,降低并发度。MySQL 默认为REPETABLE-READ。
InnoDB可重复读隔离级别下避免幻读
当前读
加了锁的增删改查语句。
例如:select…lock in share mode,select … for update,update,delete,insert
快照读
不加锁的非阻塞读,如select。仅在隔离级别低于SERIALIZABLE时属于快照读。
尽管可能是InnoDB的当前读使得避免幻读,但实质上真正能使得在REPETABLE-READ、SERIALIZABLE下避免幻读,还是靠next-key锁(行锁 + gap锁)。
何为next-key锁?
其包含两部分:行锁和gap锁。
行锁:行记录上的锁。
Gap锁:Gap是索引数中插入新纪录的空隙。Gap Lock锁定一个范围,不包括记录本身。防止同一事物的两次当前读出现缓堵的情况。
在RR及更低级别的情况下是没有。
RR及SERIABLE默认支持gap锁。
- 如果where全部命中,则不会用gap锁,只会加记录锁。
全部命中,精确查询全都有。 - 如果where条件部分命中或者全不命中,则会加Gap锁。
Gap锁主要用于在非唯一索引或者不走索引的当前读中。不过不走索引时应该尽量避免走Gap锁,因为会影响表效率。
Gap锁的范围为左开右闭。