每日一诗

少年听雨歌楼上,红烛昏罗帐。壮年听雨客舟中,江阔云低,断雁叫西风。
而今听雨僧庐下,鬓已星星也。悲欢离合总无情,一任阶前,点滴到天明。
——《虞美人·听雨》

一、前言

索引是数据库很重要的一部分,今天这篇文章主要讲述几种树结构以及Mysql用到的树结构。

二、数据库索引的认识

数据库索引是一种为了加速数据表中行记录检索的数据结构。
数据库的索引存储于磁盘。

索引在 MySQL 数据库中分三类:

  • B+ 树索引
  • Hash 索引
  • 全文索引

mysql查询某表表空间与所有空间语句:

select CONCAT(ROUND(SUM(data_LENGTH)/(1024*1024),2),' M') AS '表空间',CONCAT(ROUND(SUM(INDEX_LENGTH)/(1024*1024),2),' M') AS '索引空间'
FROMinformation_schema.`TABLES`
WHERE TABLE_SCHEMA='push'
AND TABLE_NAME='message'

push-数据库名;message-表名。

三、几种树结构讲解

3.1 二叉树

首先,让我们先看一张图:

从图中可以看到,我们为 user 表(用户信息表)建立了一个二叉查找树的索引。

图中的圆为二叉查找树的节点,节点中存储了键(key)和数据(data)。键对应 user 表中的 id,数据对应 user 表中的行数据。

二叉查找树的特点就是任何节点的左子节点的键值都小于当前节点的键值,右子节点的键值都大于当前节点的键值。顶端的节点我们称为根节点,没有子节点的节点我们称之为叶节点。

如果我们需要查找 id=12 的用户信息,利用我们创建的二叉查找树索引,查找流程如下:

  • 将根节点作为当前节点,把 12 与当前节点的键值 10 比较,12 大于 10,接下来我们把当前节点>的右子节点作为当前节点。
  • 继续把 12 和当前节点的键值 13 比较,发现 12 小于 13,把当前节点的左子节点作为当前节点。
  • 把 12 和当前节点的键值 12 对比,12 等于 12,满足条件,我们从当前节点中取出 data,即 id=12,name=xm。

利用二叉查找树我们只需要 3 次即可找到匹配的数据。如果在表中一条条的查找的话,我们需要 6 次才能找到。

3.2 平衡二叉树(AVL树)

平衡二叉树就是为了解决二叉查找树退化成一颗链表而诞生了。

AVL树图解:

平衡树具有如下特点:

1、具有二叉查找树的全部特性。

2、每个节点的左子树和右子树的高度差至多等于1。

上面我们讲解了利用二叉查找树可以快速的找到数据。但是,如果上面的二叉查找树是这样的构造:

这个时候可以看到我们的二叉查找树变成了一个链表。如果我们需要查找 id=17 的用户信息,我们需要查找 7 次,也就相当于全表扫描了。 
导致这个现象的原因其实是二叉查找树变得不平衡了,也就是高度太高了,从而导致查找效率的不稳定。
为了解决这个问题,我们需要保证二叉查找树一直保持平衡,就需要用到平衡二叉树了。

平衡二叉树又称 AVL 树,在满足二叉查找树特性的基础上,要求每个节点的左右子树的高度差不能超过 1。

下面是平衡二叉树和非平衡二叉树的对比:
由平衡二叉树的构造我们可以发现第一张图中的二叉树其实就是一棵平衡二叉树。
平衡二叉树保证了树的构造是平衡的,当我们插入或删除数据导致不满足平衡二叉树不平衡时,平衡二叉树会进行调整树上的节点来保持平衡。具体的调整方式这里就不介绍了。

平衡二叉树相比于二叉查找树来说,查找效率更稳定,总体的查找速度也更快。

3.3 红黑树

红黑树是一种自平衡二叉查找树,是一种特殊的平衡二叉树,是计算机科学领域中的一种数据结构。

红黑树的应用:java中的TreeMap、HashMap等。

红黑树出现原因:

虽然平衡树解决了二叉查找树退化为近似链表的缺点,能够把查找时间控制在 O(logn),不过却不是最佳的,因为平衡树要求每个节点的左子树和右子树的高度差至多等于1,这个要求实在是太严了,导致每次进行插入/删除节点的时候,几乎都会破坏平衡树的第二个规则,进而我们都需要通过左旋和右旋来进行调整,使之再次成为一颗符合要求的平衡树。

显然,如果在那种插入、删除很频繁的场景中,平衡树需要频繁着进行调整,这会使平衡树的性能大打折扣,为了解决这个问题,于是有了红黑树。

红黑树图示:

红黑树的特性:

  1. 每个结点是黑色或者红色。
  2. 根结点是黑色。
  3. 每个叶子结点(NIL)是黑色。 [注意:这里叶子结点,是指为空(NIL或NULL)的叶子结点!]
  4. 如果一个结点是红色的,则它的子结点必须是黑色的。
  5. 每个结点到叶子结点NIL所经过的黑色结点的个数一样的。(确保没有一条路径会比其他路径长出两倍,所以红黑树是相对接近平衡的二叉树的!)

上面的这些约束保证了这个树大致上是平衡的,这也决定了红黑树的插入、删除、查询等操作是比较快速的。

  • 如果新节点的父节点为黑色节点,那么插入一个红点将不会影响红黑树的平衡,此时插入操作完成。红黑树比AVL树优秀的地方之一在于黑父的情况比较常见,从而使红黑树需要旋转的几率相对AVL树来说会少一些。
  • 如果新节点的父节点为红色节点,这时就需要进行一系列操作以保证整棵树红黑性质;例如左旋、右旋。

红黑树的左旋操作:
假设待左旋的结构中,P为父节点,S为孩子节点。左旋操作后,S节点代替P节点的位置,P节点成为S节点的左孩子,S节点的左孩子成为P节点的右孩子。

红黑树的右旋操作:
假设待右旋的结构中,P为父节点,S为孩子节点。右旋操作后,S节点代替P节点的位置,P节点成为S节点的右孩子,S节点的右孩子成为P节点的左孩子。

扩展文章:红黑树原理
红黑树原理和算法介绍

四、B树

4.1 B树

表的数据和索引都是放在磁盘中的,和内存相比,读取磁盘的速度比读取内存要慢上百倍千倍,所以我们应尽量减少读取磁盘的次数。另外,从磁盘中读取数据时,都是按照磁盘块来读取的,并不是一条一条的读。如果我们用树这种数据结构作为索引的数据结构,那我们每查找一次数据就需要从磁盘中读取一个节点,也就是我们说的一个磁盘块。

按照少读取磁盘的原则,平衡二叉树就有缺点了:平衡二叉树,每个节点只存一个键值和数据,那说明每个磁盘块仅存一个键和数据,如果海量数据呢?可以想象节点会很多,高度也会特别高。查询数据时磁盘会经过很多次IO,查询效率会极低。

为了解决平衡二叉树的这个弊端,我们应该寻找一种单个节点可以存储多个键和数据的平衡树。也就是B树。

B树(Balance tree),又叫平衡多路查找树。
B树与二叉平衡树最大的不同在于,B树的结点可以有许多子女,从几个到几千个。

下图就是一颗B树:

图中的 p 节点为指向子节点的指针,二叉查找树和平衡二叉树其实也有,因为图的美观性,被省略了。

:图中的每个节点称为页,页就是我们上面说的磁盘块,在 MySQL 中数据读取的基本单位都是页,所以我们这里叫做页更符合 MySQL 中索引的底层数据结构。

关键字:即上图中的17,35;关键字个数=子节点岔路树-1

从上图可以看出,B 树相对于平衡二叉树,每个节点存储了更多的键值(key)和数据(data),并且每个节点拥有更多的子节点,子节点的个数一般称为阶,上述图中的 B 树为 3 阶 B 树,高度也会很低。

基于以上特性,B树查找数据读取磁盘的次数会很少,数据查找效率会比平衡二叉树高很多。

假如我们要查找 id=28 的用户信息,那么我们在上图 B 树中查找的流程如下:

  • 先找到根节点也就是页 1,判断 28 在键值 17 和 35 之间,那么我们根据页 1 中的指针 p2 找到页 3。
  • 将 28 和页 3 中的键值相比较,28 在 26 和 30 之间,我们根据页 3 中的指针 p2 找到页 8。
  • 将 28 和页 8 中的键值相比较,发现有匹配的键值 28,键值 28 对应的用户信息为(28,bv)。

五、B+数

B+ 树是对 B 树的进一步优化。让我们先来看下 B+ 树的结构图:

B+树与B树的区别

  • 根节点和支节点不报存数据区,数据区都保存在叶子节点的末尾上。
  • 叶子节点中的数据是通过单向链表连接的,页与页之间形成双向链表,有利于排序、范围查找等功能。

根节点和支节点不保存数据区,数据区都保存在叶子节点的末尾上。这个区别解决了什么问题?

——拿InnoDb来说,根节点和支节点不保存数据区,InnoDb每一页大小为16k,每一页可以存的关键字就多了很多,减少了IO的读取。

上图中的 B+ 树索引就是 InnoDB 中 B+ 树索引真正的实现方式,准确的说应该是聚集索引(聚集索引和非聚集索引下面会讲到)。

B+树的优势

  • B+树是B-树的Plus版本
  • IO效率高于B-树
  • 基于索引的表扫描性能大于B-树
  • 排序能力强于B树
  • 基于索引的查询,B树更趋于稳定

Mysql索引的本质深入浅出(一)相关推荐

  1. 数据库应用——MySQL索引的本质笔记

    索引的本质笔记 索引的本质 二叉搜索树.红黑树.B+树的简单介绍 二叉搜索树(Binary Search Tree) 红黑树(Red-Black Tree) B-树 B+树 hash表 mylsam索 ...

  2. mysql的索引本质是一颗_一文揭开Mysql索引本质

    文章目录 什么是索引 索引的分类 索引的本质 HASH B+树 Mysql存储引擎 InnoDB MyISAM 试验 结语 什么是索引 众所周知,索引是用来加快数据库查询速度的,试想一条sql语句:s ...

  3. MySQL索引背后的数据结构及算法原理【转】

    http://blog.codinglabs.org/articles/theory-of-mysql-index.html MySQL索引背后的数据结构及算法原理[转] 摘要 本文以MySQL数据库 ...

  4. mysql中groupby会用到索引吗_开发人员不得不知的MySQL索引和查询优化

    本文主要总结了工作中一些常用的操作及不合理的操作,在对慢查询进行优化时收集的一些有用的资料和信息,本文适合有 MySQL 基础的开发人员. 索引相关 索引基数 基数是数据列所包含的不同值的数量,例如, ...

  5. mysql索引底层实现原理_mysql的索引底层之实现原理

    MySQL索引背后的数据结构及算法原理 一.定义 索引定义:索引(Index)是帮助MySQL高效获取数据的数据结构. 本质:索引是数据结构. 二.B-Tree m阶B-Tree满足以下条件: 1.每 ...

  6. ElasticSearch 索引 VS MySQL 索引

    前言 这段时间在维护产品的搜索功能,每次在管理台看到 elasticsearch 这么高效的查询效率我都很好奇他是如何做到的. 这甚至比在我本地使用 MySQL 通过主键的查询速度还快. 为此我搜索了 ...

  7. Mysql 索引原理及优化

    本文内容主要来源于互联网上主流文章,只是按照个人理解稍作整合,后面附有参考链接. 一.摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引 ...

  8. 转:MySQL索引原理及慢查询优化

    来自:http://tech.meituan.com/mysql-index.html MySQL凭借着出色的性能.低廉的成本.丰富的资源,已经成为绝大多数互联网公司的首选关系型数据库.虽然性能出色, ...

  9. python mysql索引 优化神器explain 慢查询

    ##############总结########## 数据库中专门帮助用户快速找到数据的一种数据结构 类似于字典的目录的索引 索引的作用:约束和加速查找 工作原理: b+树形结构 最上层是树根,中间是 ...

最新文章

  1. 在线学位课程_您在四年制计算机科学学位课程中学到的知识
  2. 转载 CreateWaitableTimer和SetWaitableTimer函数
  3. Spark Streaming 编程新手入门指南
  4. 慕课乐学python编程题_中国大学MOOC的APP(慕课)2020Python编程基础题目及答案
  5. jQuery.ready in CRM Fiori Opportunity Application
  6. 2007 Office System Beta2 Technical Refresh 下载
  7. 90-40-010-源码-CUBE-引擎为MR写入Habse的构建
  8. POJ1426-Find The Multiple-深度优先搜索BFS
  9. python调试利器pysnooper
  10. jQuery form插件使用详解
  11. python之collections模块Counter类使用学习
  12. xp谷歌浏览器时间快了_Win7系统零日漏洞曝光,谷歌建议:升级Windows 10
  13. [精简]托福核心词汇23
  14. FreeType字体程序库介绍(转)
  15. C++20 span
  16. java-POI的Excel默认字体和样式
  17. mysql-8.0.28-winx64安装步骤
  18. WLST 命令和变量
  19. Qt利用JavaScript访问网页元素(百度博客下载例子)
  20. 世界杯感悟--我的2022卡塔尔世界杯

热门文章

  1. ABP实践(5)-abp前端vue框架之IView实现三级菜单(博友需要特此分享)
  2. 魅族手机怎么把计算机放到桌面,魅族手机怎么与电脑互传文件 如何访问电脑文件...
  3. php apache win7,win7配置Apache24和PHP7.2.4开发环境
  4. HTTP协议详解以及URL具体访问过程
  5. JS 高级(二)闭包、封装
  6. Mybatis最入门---分页查询(逻辑分页与SQL语句分页)
  7. 基于MATLAB完成卷积运算,基于Matlab的离散卷积
  8. 【CS231n assignment 2022】Assignment 2 - Part 1,全连接网络的初始化以及正反向传播
  9. python爬取12306列车信息自动抢票并自动识别验证码(一)列车数据获取篇
  10. Spring三大核心思想详解