MySQL 树形索引结构 B树 B+树

 

如何评估适合索引的数据结构

  • 索引的本质是一种数据结构
  • 内存只是临时存储,容量有限且容易丢失数据。因此我们需要将数据放在硬盘上。
  • 在硬盘上进行查询时也就产生了硬盘的I/O操作,而硬盘的I/O存取消耗的时间要比读取内存大很多。因此数据查询的时间主要决定于I/O操作的次数
  • 每访问一次节点就需要对磁盘进行一次I/O操作

 

树模型

二分查找的时间复杂度是O(log2n),是一种很高效的查询方式。在一系类树种使用二分查找的树有很多,但并不是所有树都适合作为索引的结构。

 

Binary Search Tree 二叉搜索树(BST)

性质:

  • 对任意节点,左子树不为空则左子树所有节点小于或等于该节点的值
  • 对任意节点,右子树不为空则右子树所有节点大于或等于该节点的值

但二叉搜索树不一定是"平衡的",它有可能退化成一条链表,那么他的搜索时间就变成了O(n)。

 

平衡二叉搜索树(AVL)

为了避免退化成一条链表,人们提出了二叉搜索树,AVL在二叉搜索树的基础上增加了约束:

每个节点的左子树和右子树的高度差不能超过1

也就是说要求节点的左右子树仍然为平衡二叉树。

常见的平衡二叉树有很多种,包括了AVL树、红黑树、数堆、伸展树。AVL树是最早提出来的自AVL树,当我们提到平衡二叉树时一般指的就是AVL树

左右平衡后就使得搜索时间复杂度能稳定在O(log2n)。

但是即便在理论上它的搜索效率高且比较稳定,但是由于“每访问一次节点就需要进行一次磁盘I/O操作”,在实际情况中只有两个子节点的情况下,树的高度依然有可能会很高,比如说现有一个五层共31个节点的树,那么我们需要进行5次I/O操作。

 

B Tree

既然"二叉"结构可能让树变得很高,那么我们自然而然地就明白可以让子节点数变得更多来减少I/O次数。在文件系统和部分数据库系统中,B树就已经得到了实际的应用。

如图所示,B树有如下性质

  • B树也是平衡的,每个节点可以有M个子节点,M也称为B树的阶

  • 每个磁盘块都包含着关键字和指针,有k-1个关键字,那么就有k个指针,也就是k个子节点。也就等同于子节点的数量=关键字数量+1

  • 所有子节点都在同一层,且每个叶子节点没有子节点,只包含k-1个关键字

  • 子节点和非子节点都即保存数据记录又保存索引。

  • k-1个关键字相当于划分出了k个范围,每个范围对应一个指针。

    例如,有关键字Key[1], Key[2], …, Key[k-1],且关键字按照升序排序

    它们划分出k个范围对应k个指针,P[1], P[2], …, P[k]

    对应关系就是:P[1]指向关键字小于 Key[1]的子树,P[i]指向关键字属于 (Key[i-1], Key[i]) 的子树,P[k]指向关键字大于 Key[k-1]的子树

在B树上的搜索过程就是:

  • 要找目标关键字n,那么就从根节点开始,不断在树的每一层的每两个相邻关键字划定的范围中寻找包含目标关键字的节点,顺着索引一直寻找,直到某节点中关键字与目标关键字相同。

这里说的关键字在实际的数据库中,其实就是一条实际的数据或者主键值,详细可见此处

MongoDB内部使用的就是B树

 

B+ Tree

主流的RDMS大多采用B+树作为索引结构,包括MySQL的InnoDB引擎(不同存储引擎的索引的工作方式并不一样。而即使多个存储引擎支持同一种类型的索引,其底层的实现也可能不同)

在数据结构性质上与B树不同的是:

  • 有K个孩子就有k个关键字。通俗来讲,B树是给每一个范围一个指针,而B+树是给每个子节点直接给一个指针。
  • 只有叶子节点保存数据记录,非叶子节点仅用于索引
  • 所有关键字都在叶子节点中。每层子节点的关键字也会保存在下一层子节点中且是子节点关键字中最大或最小的那一个,这样到最后,所有关键字都集合在叶子节点中。
  • 叶子节点之间会按照关键字的大小从小到大,使用双向链表进行串联。支持了区间查询。

 

B+树 vs B树

上面说了两种数据结构性质上的不同,下面里对比下实际生产中两种索引结构的区别。

  • B+树查询效率更稳定

    B+树所有的数据记录都在叶子节点,而B树的数据记录可能在叶子节点也可能在非叶子节点,这样就会导致查询效率的不稳定。

  • B+树查询效率更高

    B+树的内部节点并没有指向关键字具体信息的指针,因此其内部节点相对B树更小。那么盘块所能容纳的关键字数量也越多,一次性读入内存的需要查找的关键字也就越多,相对IO读写次数就降低了。

  • B+树的范围查询效率更高

    B+树所有叶子节点都通过双向链表进行查询,方便范围查询。

    而B树因为在非叶子节点中也存有数据记录,因此范围查询时需要通过对树的中序遍历才能完成

 

其他索引见此

 

MySQL 树形索引结构 B树 B+树的更多相关文章

  1. mysql系列十、mysql索引结构的实现B+树/B-树原理

    一.MySQL索引原理 1.索引背景 生活中随处可见索引的例子,如火车站的车次表.图书的目录等.它们的原理都是一样的,通过不断的缩小想要获得数据的范围来筛选出最终想要的结果,同时把随机的事件变成顺序的 ...

  2. 一文读懂MySQL的索引结构及查询优化

    回顾前文: 一文学会MySQL的explain工具 (同时再次强调,这几篇关于MySQL的探究都是基于5.7版本,相关总结与结论不一定适用于其他版本) MySQL官方文档中(https://dev.m ...

  3. mysql的索引为什么要使用B+树而不是其他树?

    总结 1.InnoDB存储引擎的最小存储单元是页,页可以用于存放数据也可以用于存放键值+指针,在B+树中叶子节点存放数据,非叶子节点存放键值+指针. 2.索引组织表通过非叶子节点的二分查找法以及指针确 ...

  4. MySQL索引结构之B+树索引(面)

    首先要明白索引(index)是在存储引擎(storage engine)层面实现的,而不是server层面.不是所有的存储引擎都支持所有的索引类型.即使多个存储引擎支持某一索引类型,它们的实现和行为也 ...

  5. Mysql索引数据结构为什么是B+树?

    目录 Mysql索引数据结构 二叉树 红黑树 B-Tree B+Tree Mysql索引数据结构 下面列举了常见的数据结构 二叉树 红黑树 Hash表 B-Tree(B树) Select * from ...

  6. MySQL 索引结构 hash 有序数组

    MySQL 索引结构 hash 有序数组 除了最常见的树形索引结构,Hash索引也有它的独到之处.   Hash算法 Hash本身是一种函数,又被称为散列函数. 它的思路很简单:将key放在数组里,用 ...

  7. 数据库为什么要用B+树结构--MySQL索引结构的实现(转)

    B+树在数据库中的应用 { 为什么使用B+树?言简意赅,就是因为: 1.文件很大,不可能全部存储在内存中,故要存储到磁盘上 2.索引的结构组织要尽量减少查找过程中磁盘I/O的存取次数(为什么使用B-/ ...

  8. 索引很难么?带你从头到尾捋一遍MySQL索引结构,不信你学不会!

    前言 Hello我又来了,快年底了,作为一个有抱负的码农,我想给自己攒一个年终总结.自上上篇写了手动搭建Redis集群和MySQL主从同步(非Docker)和上篇写了动手实现MySQL读写分离and故 ...

  9. 带你从头到尾捋一遍MySQL索引结构(2)

    前言 Hello我又来了,快年底了,作为一个有抱负的码农,我想给自己攒一个年终总结.索性这次把数据库中最核心的也是最难搞懂的内容,也就是索引,分享给大家. 这篇博客我会谈谈对于索引结构我自己的看法,以 ...

随机推荐

  1. java实现第四届蓝桥杯幸运数

    幸运数 题目描述 幸运数是波兰数学家乌拉姆命名的.它采用与生成素数类似的"筛法"生成. 首先从1开始写出自然数1,2,3,4,5,6,- 1 就是第一个幸运数. 我们从2这个数开始 ...

  2. Python基础语法之“print()”函数

    print()函数是Python入门的第一个必学知识点,它经常被用来调试已写的代码,检验效果,今天小老鼠就带你盘点一下print()函数在Python中如何使用. print()函数的工作流程是这样的 ...

  3. .Net Core 会逆袭成为最受欢迎开发平台吗?

    本文由葡萄城技术团队于博客园原创并首发 转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. .Net Core 是什么? 最新.Net Core 热词霸占了各个 ...

  4. thinkphp5升级thinkphp6完整步骤

    在php.ini文件中  打开  php_openssl扩展,去掉前面的;extension=php_openssl.dll 在phpstudy的WWW目录打开cmd,输入composer creat ...

  5. KMP 知识点整理

    1.扩展KMP 2.最大表示法 3.最小表示法 (扩展KMP) hdu2594  模板题 #include <iostream> #include <cstdio> #incl ...

  6. 【百度前端技术学院 Day7/8】布局

    1. 定位 1.1 文档流 单个元素: 块级元素:内容宽度是其父元素的宽度的100%,并且与其内容一样高. 内联(行内)元素:高宽与他们的内容高宽一样.(所以不能为他们设置宽高) 元素之间的交互: 块 ...

  7. vs2010静态编译qt5.1.0

    本博文参考 http://blog.chinaunix.net/uid-20690340-id-3802197.html 静态库在链接的时候直接写入二进制文件里,这样的好处在于发布的时候无需附带dll ...

  8. [转]记一次linux(被)入侵,服务器变矿机~

    0x00 背景 周一早上刚到办公室,就听到同事说有一台服务器登陆不上了,我也没放在心上,继续边吃早点,边看币价是不是又跌了.不一会运维的同事也到了,气喘吁吁的说:我们有台服务器被阿里云冻结了,理由:对 ...

  9. netty集群(一)-服务注册发现

    上篇文章介绍了如何搭建一个单机版本的netty聊天室:https://www.jianshu.com/p/f786c70eeccc. 一.需要解决什么问题: 当连接数超过单机的极限时,需要将netty ...

  10. 解决Zabbix 5.0不能选择中文和中文乱码问题

    Zabbix web界面不能选择中文,提示: You are not able to choose some of the languages, because locales for them ar ...