索引的定义:帮助MySQL高效获取数据的数据结构,可以简单理解为“排好序的快速查找B+树数据结构”。
B+树中的B代表的是平衡(balance),而不是二叉(binary)。
B树(balance tree多路平衡查找树):(B-树就是B树,中间的横线并不是减号)
B+树(加强多路查找树)
为什么选择B+树:
使用反推的方式来看:
1.没有索引:全部遍历(数据量小,时间复杂性O(n))
2.Hash:时间复杂度是O(1),遍历只进行一次,{哈希对于增删改查的平均时间复杂度都是O(1),树结构,例如平衡二叉搜索树,增删改查的平均时间复杂度都是O(log2(n)),因此可见不管是读请求还是写请求,哈希类型的索引,都要比树形索引快一些},但是对于进行范围查找和排序查找时使用哈希算法,此时时间复杂度就会变成O(n),但是使用树状结构因为其“有序”的特性,依然能够保持O(log2(n))的效率。因此InnoDB不支持hash。
3.二叉树:特点{一个节点只能有两个子节点,也就是一个节点度不能查过2;左子节点小于本节点,右子节点大于本节点},对该二叉树的节点进行查找发现:{
深度为1的节点的查找次数为1,
深度为2的节点的查找次数为2,
深度为N的节点的查找次数为N,
结论:此二叉树的平均查找次数为(1+2+2+3+3+3)/6=2.3次},但是对于普通二叉树存在连个问题:1.如果id的值是持续递增的,此时就会出现,此时树就会退化成链表,此时查找时间复杂度从Log2(n)变成O(n);2.
4.平衡二叉树(AVL树):,添加新的元素时根节点会发生变化,理论上查找大小为10的元素,此时节点高度为4,此时与磁盘交互4次就可以,但同时存在问题,如果数据库数量变大时,树高就也会变高,此时遍历次数就会增多,io量越大。
5.B树(又称为23树,一个节点上可能有2枝,也可能有3枝):
,{底层原理:1.数据库索引时存储在磁盘上的,如果数据量很大,必然导致索引的大小也会很大,2.当我们使用索引进行查询的时候,是不可能将几个G的索引都加载进内存的,能做的只能是: 逐一加载每一个磁盘页,因为磁盘页对应着索引树的节点,(系统熊磁盘中读取数据时是以磁盘块为基本单位的,位于同一磁盘块中的数据会被一次性读取出来,而不是需要什么取什么。InnoDB存储引擎中有页(page)的概念,页是磁盘管理中的最小单位,系统中一个磁盘存储空间往往没有那么大,一次InnoDB每次申请磁盘空间都会是若干连续磁盘块来达到页的大小16kb,InnoDB在把磁盘数据读到磁盘是会以页为基本单位,在查询数据时如果一个页中的每条数据都能有助于帮助定位数据记录的位置,这将会减少磁盘I/O次数,提高查询效率)}B树比平衡二叉树减少一次IO操作,
6.B+树:
由图可见所有的data数据都移动到叶子节点中,而且子节点和子节点之间会有指针指向,这就是B+树的核心点,这样可以大大提高查询效率,方便便利整个树{
1 .非叶子节点不再存储数据,数据只存储再同一层的叶子节点上 2 .叶子之间,增加了链表,获取所有节点,不在需要中序遍历}什么是中序遍历:中序遍历首先遍历左子树,然后访问根节点,最后遍历右子树,若二叉树为空则结束返回
由此可见在B树的结构图中可以看到每个节点不止包含数据的key值,同时还有data值,而每一页的存储空间是有限的,如果data数据较大时会导致每个节点(既每一个页)能存储的key值很小,到存储的数据量很大时同样会导致B树的深度较大,增加查询时磁盘IO次数从而影响查询效率,
但是在B+树中,所有数据记录节点都是按照键值大小顺序存放在同一层的叶子节点上,而非叶子节点只存储key值信息,这样就可以大大加大每个节点存储的key值数量,降低B+树的高度。
PS:B+树算法通过继承B树的特征,B+树相比与B树新增叶子节点和非叶子节点关系,叶子节点中包含键值和数据,非叶子节点中只包含键值和子节点引用,不包含数据,通过非叶子节点查询叶子节点获取对应的数据,所有相邻的叶子节点包含非叶子节点使用链表进行结合,叶子节点时顺序并且相邻节点有顺序引用的关系。