程序员MySQL 数据库专家

B-/B+树看 MySQL索引结构

2019-01-18  本文已影响13人  似水牛年

B-树

B-树,这里的 B 表示 balance( 平衡的意思),B-树是一种多路自平衡的搜索树。
它类似普通的平衡二叉树,不同的一点是B-树允许每个节点有更多的子节点。

下图是 B-树的简化图:


B-树

B-树有如下特点:

B+ 树

B+树是B-树的变体,也是一种多路搜索树, 它与 B- 树的不同之处在于:

简化 B+树 如下图:


B+树

为什么使用B-/B+ 树

红黑树等数据结构也可以用来实现索引,但是文件系统及数据库系统普遍采用B-/+Tree作为索引结构。

MySQL 是基于磁盘的数据库系统,索引往往以索引文件的形式存储的磁盘上,索引查找过程中就要产生磁盘I/O消耗,相对于内存存取,I/O存取的消耗要高几个数量级,索引的结构组织要尽量减少查找过程中磁盘I/O的存取次数。

为什么使用B-/+Tree,还跟磁盘存取原理有关。

局部性原理与磁盘预读

由于磁盘的存取速度与内存之间效率差异比较大,为了提高效率,要尽量减少磁盘I/O,磁盘往往不是严格按需读取,而是每次都会预读,磁盘读取完需要的数据,会顺序向后读一定长度的数据放入内存。而这样做的理论依据是计算机科学中著名的局部性原理

当一个数据被用到时,其附近的数据也通常会马上被使用,程序运行期间所需要的数据通常比较集中

由于磁盘顺序读取的效率很高(不需要寻道时间,只需很少的旋转时间),因此对于具有局部性的程序来说,预读可以提高I/O效率.预读的长度一般为页(page)的整倍数。

MySQL(使用InnoDB引擎),将记录按照页的方式进行管理,每页大小默认为16K(这个值可以修改).linux 默认页大小为4K

使用B+树的优势

MySQL索引实现

MySQL存在多种存储引擎的选择,不同存储引擎对索引的实现是不同的,下面对常见存储引擎InnoDB和MyISAM存储引擎的索引实现进行讨论

InnoDB索引实现

使用B+树作为索引结构,数据文件本身就是索引文件。数据文件按照B+树的结构进行组织,叶节点的data域存储完整的数据记录,索引的key即为表的主键。
下图为 主键索引 示意图。

InnoDB主索引

可以看到叶节点包含了完整的数据记录,这种索引叫做聚集索引,聚集索引使得搜索主键非常高效。

因为InnoDB的数据文件本身要按主键聚集,所以InnoDB要求表必须有主键(MyISAM可以没有),如果没有显式指定,则MySQL系统会自动选择一个可以唯一标识数据记录的列作为主键,如果不存在这种列,则MySQL自动为InnoDB表生成一个隐含字段作为主键,这个字段长度为6个字节,类型为长整形。

下图为辅助索引示意图,InnoDB辅助索引的data域存储的是主键的值。搜索辅助索引需要先根据辅助索引获取到主键值,再根据主键到主索引中获取到对应的数据记录。

InnoDB辅助索引
MyISAM索引实现

MyISAM引擎使用B+Tree作为索引结构,叶节点的data域存放的是数据记录的地址。下图是MyISAM索引的原理图:

MyISAM主索引

假设我们以Col1为主键,可以看出MyISAM的索引文件仅仅保存数据记录的地址。

在MyISAM中,主索引和辅助索引(Secondary key)在结构上没有任何区别,只是主索引要求key是唯一的,而辅助索引的key可以重复。
如果我们在Col2上建立一个辅助索引,则此索引的结构如下图所示:


MyISAM辅助索引
上一篇下一篇

猜你喜欢

热点阅读