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. 彻底搞懂 etcd 系列文章(一):初识 etcd

    0 专辑概述 etcd 是云原生架构中重要的基础组件,由 CNCF 孵化托管.etcd 在微服务和 Kubernates 集群中不仅可以作为服务注册与发现,还可以作为 key-value 存储的中间件 ...

  2. dfs算法总结

    DFS 深度优先搜索 主要有两种实现方法:栈和递归 什么是DFS?说白了就是一直遍历元素的方式而已,我们可以把它看成是一条小蛇,在每个分叉路口随意选择一条路线走,直到撞到南墙,才会调头返回到上一个分叉 ...

  3. 智能家居巨头 Aqara 基于 KubeSphere 打造物联网微服务平台

    背景 从传统运维到容器化的 Docker Swarm 编排,从 Docker Swarm 转向 Kubernetes,然后在 Kubernetes 运行 SpringCloud 微服务全家桶,到最终拥 ...

  4. [原创][开源] SunnyUI.Net 字体图标

    SunnyUI.Net, 基于 C# .Net WinForm 开源控件库.工具类库.扩展类库.多页面开发框架 Blog: https://www.cnblogs.com/yhuse Gitee: h ...

  5. Vue —— 精讲 VueRouter(1)

    最近被Boos调去给新人做培训去了,目前把自己整理的一些东西分享出来,希望对大家有所帮助 本章节为VueRouter前端 路由的章节部分 大纲 一.基本概念 路由就是通过网络把讯息从源地址传输到目的地 ...

  6. 商城02——dubbo框架整合_商品列表查询实现_分页

    1.   课程计划 1.服务中间件dubbo 2.SSM框架整合. 3.测试使用dubbo 4.后台系统商品列表查询功能实现. 5.监控中心的搭建 2.   功能分析 2.1. 后台系统所用的技术 框 ...

  7. PN532模块连接-读卡失败原因

    第一步:点击发现NFC设备 第二步:点击读整卡:读取卡片内容. 若不成功,把UID卡移开,再放一次.再点第一步,显示发现NFC,再点第二步.反复操作,直到读取到为止.2-3次一般都会成功 . 相关软件 ...

  8. Linux监控CPU,内存,磁盘I/O

    简单讲讲Linux下监控 [CPU] 监控CPU,top命令能够实时监控系统的运行状态,并且可以按照CPU.内存和执行时间进行排序,同时top命令还可以通过交互式命令进行设定显示,通过top命令可以查 ...

  9. 138 张图带你 MySQL 入门

    SQL 基础使用 MySQL 是一种关系型数据库,说到关系,那么就离不开表与表之间的关系,而最能体现这种关系的其实就是我们接下来需要介绍的主角 SQL,SQL 的全称是 Structure Query ...

  10. opencv 单通道合并为多通道

    int main(){ cv::Mat m1=(cv::Mat_<int>(,)<<,,,,,); cv::Mat m2=(cv::Mat_<int>(,)< ...