索引的存储结构

索引存储结构

索引是在存储引擎中实现的,也就是说不同的存储引擎,会使⽤不同的索引
MyISAM和InnoDB存储引擎:只⽀持B+ TREE索引, 也就是说默认使⽤BTREE,不能够更换
MEMORY/HEAP存储引擎:⽀持HASH和BTREE索引
B树和B+树
数据结构示例⽹站:
https://www.cs.usfca.edu/~gal...
B树图示
B树是为了磁盘或其它存储设备⽽设计的⼀种多叉(下⾯你会看到,相对于⼆叉,B树每个内结点有多个分⽀,即多叉)平衡查找树。 多叉平衡
image.png
B树的⾼度⼀般都是在2-4这个⾼度,树的⾼度直接影响IO读写的次数。
如果是三层树结构---⽀撑的数据可以达到20G,如果是四层树结构---⽀撑的数据可以达到⼏⼗T

B树和B+树的区别
B树和B+树的最⼤区别在于⾮叶⼦节点是否存储数据的问题。

  • B树是⾮叶⼦节点和叶⼦节点都会存储数据。
  • B+树只有叶⼦节点才会存储数据,⽽且存储的数据都是在⼀⾏上,⽽且这些数据都是有指针指向的,也就是有顺序的。 索引列 order by

⾮聚集索引(MyISAM)
B+树叶⼦节点只会存储数据⾏(数据⽂件)的指针,简单来说数据和索引不在⼀起,就是⾮聚集索引。
⾮聚集索引包含主键索引和辅助索引都会存储指针的值

主键索引
image.png
这⾥设表⼀共有三列,假设我们以 Col1 为主键,则上图是⼀个 MyISAM 表的主索引(Primary key)示意。
可以看出 MyISAM 的索引⽂件仅仅保存数据记录的地址。
image.png

辅助索引(次要索引)
在 MyISAM 中,主索引和辅助索引(Secondary key)在结构上没有任何区别,只是主索引要求 key 是唯⼀的,⽽辅助索引的 key 可以重复。如果我们在 Col2 上建⽴⼀个辅助索引,则此索引的结构如下图所示
image.png
同样也是⼀颗 B+Tree,data 域保存数据记录的地址。因此,MyISAM 中索引检索的算法为⾸先按照B+Tree 搜索算法搜索索引,如果指定的 Key 存在,则取出其data 域的值,然后以 data 域的值为地址,读取相应数据记录。

聚集索引(InnoDB)
主键索引(聚集索引)的叶⼦节点会存储数据⾏,也就是说数据和索引是在⼀起,这就是聚集索引。
辅助索引只会存储主键值
如果没有没有主键,则使⽤唯⼀索引建⽴聚集索引;如果没有唯⼀索引,MySQL会按照⼀定规则创建聚集索引。

主键索引
1.InnoDB 要求表必须有主键(MyISAM 可以没有),如果没有显式指定,则 MySQL系统会⾃动选择⼀个可以唯⼀标识数据记录的列作为主键,如果不存在这种列,则MySQL ⾃动为 InnoDB 表⽣成⼀个隐含字段作为主键,类型为⻓整形。
image.png
上图是 InnoDB 主索引(同时也是数据⽂件)的示意图,可以看到叶节点包含了完整的数据记录。这种索引叫做聚集索引。因为 InnoDB 的数据⽂件本身要按主键聚集

辅助索引(次要索引)
2.第⼆个与 MyISAM 索引的不同是 InnoDB 的辅助索引 data 域存储相应记录主键的值⽽不是地址。换句话说,InnoDB 的所有辅助索引都引⽤主键作为 data 域。
image.png
聚集索引这种实现⽅式使得按主键的搜索⼗分⾼效,但是辅助索引搜索需要检索两遍索引:⾸先检索辅助索引获得主键,然后⽤主键到主索引中检索获得记录。
select * from user where name='Alice' 回表查询 检索两次 ⾮主键索引 --- pk---索引--->数据
select id,name from user where name='Alice' 不需要回表 在辅助索引树上就可以查询到了 覆盖索引(多⽤组合索引)
image.png

引申:为什么不建议使⽤过⻓的字段作为主键?
因为所有辅助索引都引⽤主索引,过⻓的主索引会令辅助索引变得过⼤。
同时,请尽量在 InnoDB 上采⽤⾃增字段做表的主键。

MyISAM 和 InnoDB的存储结构图示
为了更形象说明这两种索引的区别, 我们假想⼀个表如下图存储了 4 ⾏数据。 其中Id 作为主索引,Name 作为辅助索引。 图示清晰的显示了聚簇索引和⾮聚簇索引的差异:
image.png
image.png


晗宝
175 声望218 粉丝

一个男人要保护好:脚下的土地,家里的父母,怀里的女人,身边的兄弟!!!