存储引擎
SHOW ENGINES
命令来查看 MySQL
支持的所有存储引擎;
从上图可以看出, MySQL 当前默认的存储引擎是 InnoDB
。并且所有的存储引擎中只有 InnoDB
支持事务。
MySQL 5.5.5 之前,MyISAM
是 MySQL 的默认存储引擎。5.5.5 版本之后,InnoDB
是 MySQL 的默认存储引擎。
MyISAM和InnoDB的区别?
MyISAM | InnoDB | |
---|---|---|
事务 | 不支持 | 提供事务支持,默认使用可重读 隔离级别,可解决幻读问题发生。 |
锁级别 | 仅支持表级锁,锁粒度太大,并发性能受限。 | 默认行级锁,并发性能高,且支持手动更改表级锁。 |
外键 | 不支持 | 支持外键约束,但实际开发为避免外键带来的性能问题,会选择在业务代码中进行约束。 |
索引实现 | 非聚集索引,索引(表名.MYI)和数据(表名.MYD)分开存储。 | 聚簇索引,索引文件和数据文件同时存放在表名.ibd 文件中。 |
异常恢复 | 不支持 | 支持数据库异常崩溃后的安全恢复,恢复的过程依赖于 redo log 。 |
索引
索引是一种用于快速查询和检索数据的数据结构,本质可以看成是一种排序好的数据结构。
索引是针对底层存储引擎的概念。不同的存储引擎对索引的支持和实现方式不同,服务器层在查询优化时会利用这些索引提高查询效率。
InnoDB中的索引类型
InnoDB存储引擎中,根据数据的存储形式不同,分为聚集索引
和非聚集索引
两种形式。
聚集索引
将数据存储与索引放到了一块,索引结构的叶子节点保存行数据,数据按照主键的顺序存储。一张表中必须存在聚集索引,且只能有一个,InnoDB 中的主键索引就属于聚簇索引。
聚集索引选取规则:
- 如果存在主键,主键索引就是聚集索引。
- 如果不存在主键,将使用第一个唯一(UNIQUE)索引作为聚集索引。
- 如果表没有主键,或没有合适的唯一索引,则InnoDB会自动生成一个rowid字段,作为隐藏的聚集索引。
主键索引(Primary Key)
数据表中的主键列使用的就是主键索引。
非聚集索引
将数据与索引分开存储,索引结构的叶子节点关联数据行的主键。
普通索引
在数据表的普通字段上建立的索引,称为普通索引。
唯一索引(UNIQUE)
为唯一列创建的索引。
联合索引
使用表中的多个字段创建索引,就是联合索引。
全文索引
只能在文本类型char,varchar,text类型字段上创建全文索引。
MySQL索引底层数据结构
MySQL中索引底层数据结构选取的是B+树,InnoDB默认缓存页大小为16KB(页在物理空间是不连续的,页与页之间通过指针链接),一个页可以视作B+树中的一个节点,意味着可以容纳16KB容量的数据值,到达16KB后会进行页分裂。
为什么选取B+树作为索引的底层结构?
B+树中,非叶子节点仅存储
索引值
和指向下个页的指针
,而叶子节点存储行数据(主键索引)或主键值(普通索引),非叶子节点不用像B树一样存储大量行数据,则可以容纳更多的键值,降低整个树的高度,从而减少了与磁盘IO的次数,提升了查询效率。同时叶子节点是一个双向链表,范围查询时,找到边界值后顺序遍历叶子节点即可,范围查询效率更高。
为什么不选择Hash或B树作为索引底层结构?
索引结构 | 原因 |
---|---|
Hash | 只支持等职查询,不支持范围查询。 |
B树 | 由于每个节点都存储索引值和行数据,如果行数据占用空间较大,导致树的层级会较深,查询的效率便会降低。同时B树叶子节点独立,也不支持高效范围查询。 |
B树
B树也称多路平衡查找树
,每个节点的键值是由小到大排序,它的特点如下:
- 所有节点同时存放索引值和行数据;节点中的索引值由小到大排序。
- 叶子节点独立,因此范围查需要递归从根节点遍历查找,效率较低。
B+树
B+树是B树的一种变体,它的特点如下:
- 叶子节点同时存储索引值和行数据;
- 非叶子节点仅存储
索引值
(下一页的最小索引值)和指向下个页的指针
,索引值仅仅用于引导查找。 - 所有叶子节点通过指针连接成一个有序链表,便于范围查询(找到边界值后只需要对链表进行遍历即可)。
- 检索效率稳定,任何查找都是从根节点到叶子节点的过程。
B+树的结构示例图如下: