前言
在上一篇 MySQL 索引类型 中,我们已经了解了索引的基本概念以及分类,那么,索引的结构是什么样的?为什么索引可以这么快?这一篇文章将继续探讨索引的实现原理和数据结构,主要介绍 B+ 树索引和 Hash 索引。
数据库存储单位
首先我们要知道,由于为了实现持久化,只能将索引存储在硬盘上,通过索引来进行查询的时候就会产生硬盘的 I/O 操作,因此,设计索引时需要尽可能的减少查找次数,从而减少 I/O 耗时。
此外还需要知道一个很重要的原理:数据库管理存储空间的基本单位是页(Page)
,一个页中存储多条行记录(Row)。
计算机系统对磁盘 I/O 会做预读
优化,当一次I/O时,除了当前磁盘地址的数据以外,还会把相邻的数据也读取到内存缓冲池中,每一次 I/O 读取的数据成为一页,InnoDB 默认的页大小是 16KB。
连续的 64 个页组成一个区(Extent)
,一个或多个区组成一个段(Segment)
,一个或多个段组成表空间(Tablespace)
。InnoDB 有两种表空间类型,共享表空间表示多张表共享一个表空间,独立表空间表示每张表的数据和索引全部存在独立的表空间中。
数据页结构如下(图源:极客时间《MySQL 必知必会》):
数据页的 7 个结构内容可以大致分为以下三类:
- 文件通用部分,用于校验页传输完整
- 文件头(File Header): 表述页信息,文件头中使用 FIL_PAGE_PREV 和 FIL_PAGE_NEXT 构成一个双向链表,分别指向前后的数据页。
- 页头(File Header):记录页的状态信息
- 文件尾(Fil