天天看点

MySQL(1) -- 存储引擎和索引数据结构介绍 | InnoDB索引原理 | 联合索引数据结构 | 聚簇索引

        • 1. 存储引擎:
        • 2. 索引文件:
          •  2.1. MyISAM的索引文件:
          •  2.2. InnoDB的索引文件:
        • 3. 索引类型:
          •  3.1. 主键索引(Primary Key):
          •  3.2. 二级索引(辅助索引):
        • 4. 索引数据结构:
          •  4.1. MyISAM索引实现:
          •  4.2. InnoDB 索引实现:
            •   4.2.1. InnoDB 主键索引实现:
            •   4.2.2. InnoDB 辅助索引实现:
            •   4.2.3. InnoDB 联合索引实现:
        • 5. 聚簇索引和非聚簇索引:
          •  5.1. 非聚簇索引:
          •  5.2. 非聚簇索引:
        • 6. 关于InnoDB索引小结:

1. 存储引擎:

 存储引擎是不同数据文件在磁盘上的不同组织形式
  • MySQL 5.5 之前,MyISAM 引擎是 MySQL 的默认存储引擎
  • MySQL 5.5 之后,MySQL 引入了 InnoDB(事务性数据库引擎),MySQL 5.5 版本后默认的存储引擎为 InnoDB

【区别】:

  • MyISAM 只有表级锁(table-level locking);而 InnoDB 支持行级锁(row-level locking)和表级锁,默认为行级锁。
  • MyISAM 不提供事务支持;而InnoDB 提供事务支持,具有提交(commit)和回滚(rollback)事务的能力。
  • MyISAM 不支持外键;而 InnoDB 支持。
  • MyISAM 不支持数据库异常崩溃后的安全恢复;而 InnoDB 支持,数据库重新启动的时候会保证数据库恢复到崩溃前的状态
  • MyISAM 不支持MVCC;而 InnoDB 支持。

2. 索引文件:

 在安装目录的data文件夹可以看到每个库的表文件
MySQL(1) -- 存储引擎和索引数据结构介绍 | InnoDB索引原理 | 联合索引数据结构 | 聚簇索引
 MySQL不同版本文件有些区别,MySQL8之后,没有.frm
MySQL(1) -- 存储引擎和索引数据结构介绍 | InnoDB索引原理 | 联合索引数据结构 | 聚簇索引
 2.1. MyISAM的索引文件:
MyISAM存储引擎表相关文件有三个:
  • .frm是存储表结构的
  • .MYD是存储表数据的(D代表Date)
  • .MYI是存储索引的(I代表Index)
 2.2. InnoDB的索引文件:
  • .frm是存储表结构的
  • .ibd存储数据和索引

3. 索引类型:

 3.1. 主键索引(Primary Key):
  • 数据表的主键列使用的就是主键索引。
  • 在 MySQL 的 InnoDB 的表中,当没有显示的指定表的主键时,InnoDB 会自动先检查表中是否有唯一索引的字段,如果有,则选择该字段为默认的主键,否则 InnoDB 将会自动创建一个 6Byte 的自增主键。
  • InnoDB中,主键索引的叶子节点存储的是完整数据
  • MyISAM中,主键索引的叶子节点存储的是数据地址
 3.2. 二级索引(辅助索引):
  • 唯一索引,普通索引,前缀索引等索引属于二级索引。
  • InnoDB中,辅助索引的叶子节点存储的是主键
  • MyISAM中,辅助索引的叶子节点存储的是数据地址

4. 索引数据结构:

 MySQL中,无论是MyISAM还是InnoDB,其索引数据结构都是B+树(不懂B+树的可以参考这篇文章)
 4.1. MyISAM索引实现:
 MyISAM引擎使用B+Tree作为索引结构,叶节点的data域存放的是数据记录的地址。下图是MyISAM主键索引的原理图:
MySQL(1) -- 存储引擎和索引数据结构介绍 | InnoDB索引原理 | 联合索引数据结构 | 聚簇索引
  • 假设要查找Col1为20的数据,由主键索引找到20的叶子节点,该节点的date存储数据的地址(对应.MYD的数据)
  • 根据该地址就能去.MYD文件查询到全部数据
下图是MyISAM辅助索引的原理图,在查找数据上和主键索引是一样的
MySQL(1) -- 存储引擎和索引数据结构介绍 | InnoDB索引原理 | 联合索引数据结构 | 聚簇索引
 4.2. InnoDB 索引实现:

  4.2.1. InnoDB 主键索引实现:

 下图是InnoDB 主键索引的原理图,叶子节点的key是主键,date存储了完整的表字段数据
MySQL(1) -- 存储引擎和索引数据结构介绍 | InnoDB索引原理 | 联合索引数据结构 | 聚簇索引
 比如查找主键20的数据,根据主键能找到叶子节点,该叶子节点存储了完整数据,所以就能查到所有字段数据

  4.2.2. InnoDB 辅助索引实现:

 下图是InnoDB 辅助索引的原理图,叶子节点的key是索引键,date存储的是主键。
MySQL(1) -- 存储引擎和索引数据结构介绍 | InnoDB索引原理 | 联合索引数据结构 | 聚簇索引
  • 比如查找Eric的数据,根据辅助索引找到Eric的叶子节点
  • 该节点存储了主键,想要获得其他字段数据,就要去主键再检索一边才能获取所有字段数据(也就是回表查询了)

  4.2.3. InnoDB 联合索引实现:

 联合索引和辅助索引一样,叶子节点存储的是主键,但其非叶子节点的Key由所有索引列构成。
MySQL(1) -- 存储引擎和索引数据结构介绍 | InnoDB索引原理 | 联合索引数据结构 | 聚簇索引
  • 比如有一个联合索引(b,c,d),现在要select * from table where b =3 and c=4 and d=5
  • 会先根据b=3(如果有b相同再根据c、d),从第一层非叶子节点查找,获得第二层非叶子节点地址,每从磁盘加载节点数据,就进行一次IO
  • 在第二层非叶子节点,依次匹配c=4,d=5,查找到符合的叶子节点地址,又进行了一次IO
  • 从叶子节点中获取存储的主键,根据主键去主键索引在检索一遍,获取select * 所有字段数据

5. 聚簇索引和非聚簇索引:

 InnoDB存储引擎既有聚簇索引,也有非聚簇索引(需要回表的时候)

·

 MyISAM存储引擎只有非聚簇索引,没有聚簇索引

 5.1. 非聚簇索引:
 数据跟索引存储在一起(InnoDB存储引擎的.ibd文件),像InnoDB的主键索引就是聚簇索引
 5.2. 非聚簇索引:
 数据跟索引不存储在一起(MyISAM存储引擎的.MYD和.MYI文件)

6. 关于InnoDB索引小结:

  • 非叶子节点会存储下一节点磁盘(指针)地址
  • 通过二分查找从非叶子节点查找到叶子节点,看索引类型,决定是否需要回表
  • 主键索引的叶子节点存储完整字段数据;辅助索引叶子节点存储主键,需要在去主键检索一遍才能获取所有字段数据(回表查询)

【参考】:

 MySQL索引及其数据结构

 联合索引在B+Tree上的存储结构及数据查找方式