平衡二叉树

(1)非叶子节点最多拥有两个子节点;

(2)非叶子节值大于左边子节点、小于右边子节点;

(3)树的左右两边的层级数相差不会大于1;因为平衡二叉树查询性能和树的层级(h高度)成正比、为了保证树的结构左右两端数据大致平衡降低二叉树的查询难度一般会采用一种算法机制实现节点数据结构的平衡

(4)没有值相等重复的节点;

索引

索引(Index)是帮助MySQL高效获取数据的数据结构。在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法。这种数据结构,就是索引。

目前大部分数据库系统及文件系统都采用B-Tree或其变种B+Tree作为索引结构

定义一条数据记录为一个二元组[key, data],key为记录的键值,对于不同数据记录,key是互不相同的;data为数据记录除key外的数据

B树(B-tree)

B树和平衡二叉树稍有不同的是B树属于多叉树又名平衡多路查找树(查找路径不只两个)

(1)在一个节点中,存放着数据(包括key和data)以及指针,且相互间隔

(2)同一个节点,key增序

(3)一个节点最左边的指针不为空,则它指定的节点左右的key小于最左边的key。右边同理。中间的指针指向的节点的key位于相邻两个key的中间。

(4)B-Tree中不同节点存放的key和指针可能数量不一致,但是每个节点的域和上限是一致的,所以在实现中B-Tree往往对每个节点申请同等大小的空间

(5)每个非叶子节点由n-1个key和n个指针组成,其中d<=n<=2d

数据库B-Tree检索

按key检索数据,首先与根节点key比较,如果找到则返回对应节点的data,否则对相应区间的指针指向的节点递归进行查找,直到找到节点或找到null指针,前者查找成功,后者查找失败

B+树

内节点不存储data,只存储key和指针;叶子节点不存储指针,存key和data

(1)内节点和叶子节点大小不同

(2)每个节点的指针上限为2d而不是2d+1

(3)因为它节点内部没有data,所以有更多的空间放key,所以B+树的出度一般比B-树要大,而对于一定的数据,出度大的话,树的深度就小,所以B+树的检索效率比B-树高

数据库B+Tree检索

般在数据库系统或文件系统中使用的B+Tree结构都在经典B+Tree的基础上进行了优化,增加了顺序访问指针

提高区间访问的性能,例如图4中如果要查询key为从18到49的所有数据记录,当找到18后,只需顺着节点和指针顺序遍历就可以一次性访问到所有数据节点

为什么使用B-Tree(B+Tree)做索引?

一般来说,索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储的磁盘上,换句话说,索引的结构组织要尽量减少查找过程中磁盘I/O的存取次数。

先从B-Tree分析,根据B-Tree的定义,可知检索一次最多需要访问h(树的深度)个节点。数据库系统的设计者巧妙利用了磁盘预读原理,将每次新建节点时,直接申请一个页的空间,这样就保证一个节点物理上也存储在一个页里,加之计算机存储分配都是按页对齐的,就实现了一个节点只需一次I/O。

B-Tree中一次检索最多需要h-1次I/O(根节点常驻内存),渐进复杂度为O(h)。一般实际应用中,出度d(节点最大的分支数)是非常大的数字,通常超过100,因此h非常小(通常不超过3)。

综上所述,用B-Tree作为索引结构效率是非常高的。

而红黑树这种结构,h明显要深的多。由于逻辑上很近的节点(父子)物理上可能很远,无法利用局部性,所以红黑树的I/O渐进复杂度也为O(h),效率明显比B-Tree差很多。

上文还说过,B+Tree更适合外存索引,原因和内节点出度d有关。从上面分析可以看到,d越大索引的性能越好,而出度的上限取决于节点内key和data的大小。

MySQL索引实现

MyISAM索引实现

MyISAM引擎使用B+Tree作为索引结构,MyISAM索引文件仅仅保存数据记录的地址,我们假设数据有3列,且Col1是主键,这个图就是主键的索引结构示意图,上文的key对应主键的值,叶节点的data域存放的是数据记录的地址。

MyISAM中索引检索的算法为首先按照B+Tree搜索算法搜索索引,如果指定的Key存在,则取出其data域的值,然后以data域的值为地址,读取相应数据记录。MyISAM的索引方式也叫做“非聚集”的,之所以这么称呼是为了与InnoDB的聚集索引区分

InnoDB索引实现

也是使用B+树实现索引结构,但是实现方式与上面不同,聚集索引

即data不存地址,而是直接存数据本身,即数据文件就是索引文件,

因为InnoDB的数据文件本身要按主键聚集,所以InnoDB要求表必须有主键(MyISAM可以没有),如果没有显式指定,则MySQL系统会自动选择一个可以唯一标识数据记录的列作为主键,如果不存在这种列,则MySQL自动为InnoDB表生成一个隐含字段作为主键,这个字段长度为6个字节,类型为长整形。下图是以第二列为主键的辅助索引,即主键与第二列之间的对应关系,当然在MyISAM也可以建立辅助索引

聚集索引这种实现方式使得按主键的搜索十分高效,

但是辅助索引搜索需要检索两遍索引:首先检索辅助索引获得主键,然后用主键到主索引中检索获得记录。

知道了InnoDB的索引实现后,就很容易明白为什么不建议使用过长的字段作为主键,因为所有辅助索引都引用主索引,过长的主索引会令辅助索引变得过大。再例如,用非单调的字段作为主键在InnoDB中不是个好主意,因为InnoDB数据文件本身是一颗B+Tree,非单调的主键会造成在插入新记录时数据文件为了维持B+Tree的特性而频繁的分裂调整,十分低效,而使用自增字段作为主键则是一个很好的选择。

mysql利用树建立索引_MYSQL(一)——-为什么使用B+树或者B-树做为索引结构? – 算法网...相关推荐

  1. mysql root 无法建立数据库_MySQL - 在root用户下你跟我说无法建表!?

    问题场景描述 在某次操作中,我作死用 find 和 chown 命令行修改文件/文件夹的权限和所有者,后来简单粗暴地把 www 文件夹的权限改回755[1],把文件的权限改为644:所有者全部改为ro ...

  2. mysql 异步复制建立过程_mysql生产环境高可用---基于GTID异步复制项目实施

    客户需求: 客户需要上线一个门户网站,初期业务量非常小,数据量10个G,后台需要使用msyql 数据库,需要建设一个数据库环境 项目技术: 操作系统:两台linux系统 红帽6.5 数据库版本:msy ...

  3. MySQL利用磁盘缓存写入_MySQL写入缓冲区在数据库中的作用( Change Buffer )

    原标题:MySQL写入缓冲区在数据库中的作用( Change Buffer ) 介绍另外一种重要的数据变更日志,也就是InnoDB change buffer.Change buffer的主要目的是将 ...

  4. mysql利用cpu率高_MySQL CPU 使用率高的原因和解决方法

    用户在使用 MySQL 实例时,会遇到 CPU 使用率过高甚至达到 100% 的情况.本文将介绍造成该状况的常见原因以及解决方法,并通过 CPU 使用率为 100% 的典型场景,来分析引起该状况的原因 ...

  5. mysql利用cpu率高_MySQL高CPU使用率

    首先,我想您可能要关闭持久性连接,因为它们几乎总是弊大于利. 其次,我想您要仔细检查您的MySQL用户,以确保任何人都无法从远程服务器进行连接.这也是要检查的主要安全事项. 第三,我想说你想打开MyS ...

  6. MySQL不走联合索引_mysql group by 多列优化思路?为什么不走联合索引?

    explain SELECT a, b, COUNT(*) FROM tbname GROUP BY a, b order by a DESC limit 1 a 和 b 列已经设置联合索引, 为什么 ...

  7. mysql利用binlog删除数据库_MySQL数据库之mysql手动删除BINLOG的方法

    本文主要向大家介绍了MySQL数据库之mysql手动删除BINLOG的方法 ,通过具体的内容向大家展现,希望对大家学习MySQL数据库有所帮助. 在MySQL中执行以下命令: 复制代码 代码如下: P ...

  8. MySQL利用关系代数进行查询_MySQL基础 关系代数

    MySQL基础 -- 关系代数 关系代数是一种抽象的查询语言,它用对关系的运算来表达查询.任何一种运算都是将一定的运算符作用于一定的运算对象上,得到预期的结果.所以运算对象.运算符.运算结果是运算的三 ...

  9. MySQL利用关系代数进行查询_MySQL 与关系代数

    关系代数是什么? -是MySQL查询语句的理论基础 -是一种关系运算 -运算的对象是关系,运算的过程是关系,运算的结果也是关系 关系代数的运算符号:集合运算符,比较运算符,关系运算符,逻辑运算符 关系 ...

  10. mysql主键始终从小到大_Mysql从入门到入神之(四)B+树索引

    前言 文本已收录至个人GitHub仓库,欢迎Star:github.com/bin39232820- 种一棵树最好的时间是十年前,其次是如今 我知道不少人不玩qq了,可是怀旧一下,欢迎加入六脉神剑Ja ...

最新文章

  1. spring定时任务时间格式cronExpression设置
  2. linux du -h按文件大小,【玩转linux命令】du党
  3. [转]Android开发,实现可多选的图片ListView,便于批量操作
  4. 【语言处理与Python】10.1自然语言理解\10.2命题逻辑
  5. git object 很大_这才是真正的Git——Git内部原理
  6. HDFS文件导出本地合并为一个文件
  7. 音视频开发(7)---流媒体服务器原理和架构解析
  8. opencv图像及视频感兴趣区域设置
  9. 笔记本怎样做无线打印服务器,自己的笔记本怎么连打印机_笔记本怎样无线连接打印机...
  10. 计算机网络释疑与解答第六版 pdf,计算机网络释疑与习题解答第5版.pdf
  11. burst什么意思_burst是什么意思_burst在线翻译_英语_读音_用法_例句_海词词典
  12. 关于学习的三个认知升级
  13. Spark On Yarn --jars/spark.yarn.jars 踩坑 与 提升spark submit速度
  14. 全网最详细中英文ChatGPT-GPT-4示例文档-从0到1快速入门AI智能问答应用场景——官网推荐的48种最佳应用场景(附python/node.js/curl命令源代码,小白也能学)
  15. 数字藏品交易平台如何上架数字藏品?
  16. 深度解析dubbo网络传输层Transporter
  17. NOI 国家集训队论文集
  18. VIT 三部曲 -1 Transformer
  19. 再谈单应性矩阵及位姿分解
  20. java实现两人对战的五子棋游戏

热门文章

  1. php数组的概述及分类与声明
  2. 纯JS日历控件自动输入日期到TextBox、文本框当中
  3. Cookie编码解码
  4. SQL中GROUP BY语句介绍
  5. Linux性能优化实战:CPU的上下文切换是什么意思(03)
  6. Fiddler内置命令
  7. Daily Scrum 10.28
  8. MySQL心得1--数据库的基本概念
  9. 相辅相成的知识图谱与预训练语言模型
  10. ICLR'17 | 在特征空间增强数据集