关于这个问题,我们首先要弄明白两个问题:什么是索引?什么是B+树?
索引是一种数据结构,用于帮助我们在大量数据中快速定位到我们想要查找的数据。
索引最形象的比喻就是图书的目录了。注意这里的大量,数据量大了索引才显得有意义,如果我想要在[1,2,3,4]中找到4这个数据,直接对全数据检索也很快,没有必要费力气建索引再去查找。
索引在mysql数据库中分三类:
B+树索引、Hash索引、全文索引
今天要介绍的是工作开发中最常接触到innodb存储引擎中的的B+树索引。
B+树的演化是由二叉查找树、二叉平衡树、B树三种数据结构来的。
看这张图:
顶端的节点我们称为根节点,没有子节点的节点我们称之为叶节点。
特点:任何节点的左子节点的键值都小于当前节点的键值,任何节点的右子节点的键值都大于当前节点的键值。
**缺点:**如果二叉查找树变成了一个斜线上升或者下降的链表:
就会导致二叉树变得不平衡,树的高度太高了,导致查找效率不稳定。
为了解决这种问题,保证二叉树一直平衡,就要用到平衡二叉树。
特点:树的叶子节点都差不多深,有平衡之意。要求每个节点的左右子树的高度相差不能超过1。
下面是平衡二叉树和非平衡二叉树的对比:
平衡二叉树相对于二叉查找树来说,查找效率更稳定,总体的查询速度也更快。
**缺点:**平衡二叉树每个节点只存储一个键值和数据,当存储海量的数据时,二叉树的节点会非常多,高度非常高,查找效率会极其慢。
因为从磁盘中读取数据时,都是按照磁盘块来读取的,并不是一条一条的读。 而如果我们用树这种数据结构作为索引的数据结构,那我们每查找一次数据就需要从磁盘中读取一个节点,也就是我们说的一个磁盘块。
而磁盘和内存相比,读取数据的速度要慢上百倍甚至万倍,所以查找效率极其慢。
图中的p节点为指向子节点的指针,二叉查找树和平衡二叉树其实也有,因为图的美观性,被省略了。
图中的每个节点称为页,页就是我们上面说的磁盘块,在mysql中数据读取的基本单位都是页,所以我们这里叫做页更符合mysql中索引的底层数据结构。
特点:B树相对于平衡二叉树,每个节点存储了更多的键值和数据,并且每个节点拥有更多的子节点。
子节点的个数一般称为阶,上述图中的B树为3阶B树,高度也会很低。
基于这个特性,B树查找数据读取磁盘的次数将会很少,数据的查找效率也会比平衡二叉树高很多。
B+树是对B树的进一步优化。让我们先来看下B+树的结构图:
特点:
上图中的B+树索引就是innodb中B+树索引真正的实现方式,准确的说应该是聚集索引。
MyISAM中的B+树索引实现与innodb中的略有不同。在MyISAM中,B+树索引的叶子节点并不存储数据,而是存储数据的文件地址。
在MySQL中,B+树索引按照存储方式的不同分为聚集索引和非聚集索引。
这里我们着重介绍innodb中的聚集索引和非聚集索引。
趣谈编程注:换言之,在B+树中,叶子节点存储整条记录的数据,这样的索引为聚集索引。
明白了聚集索引和非聚集索引的定义,我们应该明白这样一句话:数据即索引,索引即数据。
在MyISAM中,聚集索引和非聚集索引的叶子节点都会存储数据的文件地址。
原文地址:https://cloud.tencent.com/developer/article/1543335