MySQL专题面试题-二叉树、红黑树、B 树、B+树
演示网址:https://www.cs.usfca.edu/~galles/visualization/Algorithms.html
所谓的索引,就是帮助MySQL高效获取数据的排好序的数据结构,基本都是按照k-v形式存储。
1.二叉树
二叉树的每个节点至多只有2个叶子节点,且左边的叶子节点键值比根节点小,右边的叶子节点键值比根节点大。这些节点上都存储的索引值k,而v就是这条数据在磁盘上的首地址。下图是一棵普通的二叉树,插入的顺序是:5,3,4,2,6,7.
可以看出,当不断的插入比根节点大的值时,就会一直往右边节点添加。如果是自增的,那么右边的树深度就会高,查询效果不佳。
2.红黑树
红黑树是一种特殊的平衡二叉树,就是让节点分为红色和黑色两种,其中根节点为黑色,其插入效果如下,数据顺序还是:5,3,4,2,6,7.
可以看出,在插入时,会进行节点的旋转,以至于让其满足规则。即插入的节点键值处于当前两个节点中间时,会变化位置,以符合二叉树的规范,而且还使得树是平衡的。可想而知,这种方式在插入时,频繁的变换位置,也会影响插入效率。
3.B 树
B树也是二叉树的一种优化,但不同的是,其一个节点上可以有多个键值。其插入效果如下,数据顺序还是:5,3,4,2,6,7.
无论怎么变化,这种树都遵循二叉树的原则,也就是这些节点都是排好序的,根节点的左边节点键值比其小,右边节点键值比其大。 即使一个节点上有多个键值,也是有顺序的。
4.B+树
B+树是对B树的一种升级,区别在于在叶子节点上都有指针进行关联,而且叶子节点上也冗余存储了非叶子节点的数据。其插入效果如下,数据顺序还是:5,3,4,2,6,7.
那么在mysql的官方文档中,指出了叶子节点之间双向指针。而其最小的单位是page(页),一页是16KB(包含了页头,也目录和用户数据),数据都按照16KB的方式存到磁盘中,在查询时也是一次取出一页的数据进行判断。在数据插入时,会按照主键索引进行排序存储,上述的动态图已经很好的说明了这一点。排好序后,是非常便于查询的,当不符合条件时即可提前结束查询直接返回结果,而不至于扫描全表。但是对于其指针的特性,也是有缺陷的,如果要查询某一数据,必须按节点的先后顺序遍历很多次,因为链表插入的效率高,查询的效率低。那么此时页目录就派上用场了。页目录类似书籍的目录,对用户数据进行分组,其中目录项存储的是用户数据的起始项,结构如下图所示,左图是当只有一页时的场景,而右图是有多页时的场景。当然,又多页时,又变成了一个链表,此时就可以按照页目录的方式,对这些页再创建一个目录用来存储下面这些页目录的起始节点,而这个目录就是根节点。
那么在查询时,就可以先把页目录的数据拿出来进行比较,获取对应的组后再去用户数据区域遍历数据,减少了遍历的次数,提高了查询的效率,实际上是空间换时间的思想。
其实对于索引来说,除了B+Tree,还有hash,通过对key进行hash即可定位数据的位置,效率更高,但是其仅支持"="和"in",不支持范围查找,也会存在hash冲突问题。