B树

B树(B-tree、B-树):是一种平衡的多路搜索树,多用于文件系统、数据库的实现。

B树的特点:

  • 1个节点可以存储超过2个元素、可以拥有超过2个子节点;

  • 拥有二叉搜索树的一些性质(有序性);

  • 平衡,每个节点的所有子树高度一致;

  • 树的整体高度较低。

m阶B树的性质(m≥2)

m阶表示节点允许有m个子节点,节点元素的个数可以有m-1个。

3阶B树:

4阶B树:

B+树

B+树是B树的一种变形形式,B+树上的叶子结点存储关键字以及相应记录
的地址,叶子结点以上各层作为索引使用。

从上图我们可以归纳出B+树的几个特征:

  • 所有记录节点都是按键值的大小顺序存放在同一层的叶子节点上,由各叶子节点
    指针进行连接;

  • 相同节点数量的情况下,B+树高度远低于平衡二叉树;

  • 非叶子节点只保存索引信息和下一层节点的指针信息,不保存实际数据
    记录;

  • 只有叶子节点存储实际的数据。

B+树的变体为B树,在B+树的非根和非叶子结点再增加指向兄弟的指针;
B
树定义了非叶子结点关键字个数至少为(2/3)*M,即块的最低使用率为2/3(代
替 B+树的1/2)。

MySQL中的B+树索引结构

B+树索引是数据库系统中最为常见的一种索引数据结构,几乎所有的关系型数据库都支持它。

那为什么关系型数据库都热衷支持B+树索引呢?因为它是目前为止排序最有效率的数据结构。像二叉树,哈希索引、红黑树、SkipList,在海量数据基于磁盘存储效率方面远不如B+树索引高效。

所以,上述的数据结构一般仅用于内存对象,基于磁盘的数据排序与存储,最有效的依然是B+树索引。

B+树索引的特点是: 基于磁盘的平衡树,但树非常矮,通常为3~4层,能存放千万到上亿的排序数据。树矮意味着访问效率高,从千万或上亿数据里查询一条数据,只用 3、4 次I/O。

又因为现在的固态硬盘每秒能执行至少10000次I/O,所以查询一条数据,哪怕全部在磁盘上,也只需要0.0030.004秒。另外,因为B+树矮,在做排序时,也只需要比较34次就能定位数据需要插入的位置,排序效率非常不错。

B+树索引由根节点(root node)、中间节点(non leaf node)、叶子节点(leaf node)组成,其中叶子节点存放所有排序后的数据。当然也存在一种比较特殊的情况,比如高度为1的B+树索引:

上图中,第一个列就是B+树索引排序的列,你可以理解它是表User中的列id,类型为8字节的BIGINT,所以列userId就是索引键(key),类似下表:

CREATE TABLE User (id BIGINT AUTO_INCREMENT PRIMARY KEY,name VARCHAR(128) NOT NULL,sex CHAR(6) NOT NULL,registerDate DATETIME NOT NULL,...
)

所有B+树都是从高度为1的树开始,然后根据数据的插入,慢慢增加树的高度。你要牢记:索引是对记录进行排序, 高度为1的B+树索引中,存放的记录都已经排序好了,若要在一个叶子节点内再进行查询,只进行二分查找,就能快速定位数据。

可随着插入B+树索引的记录变多,1个页(16K)无法存放这么多数据,所以会发生B+树的分裂,B+树的高度变为 2,当B+树的高度大于等于2时,根节点和中间节点存放的是索引键对,由(索引键、指针)组成。

索引键就是排序的列,而指针是指向下一层的地址,在MySQ 的InnoDB存储引擎中占用6个字节。下图显示了B+树高度为2时,B+树索引的样子:

可以看到,在上面的B+树索引中,若要查询索引键值为5的记录,则首先查找根节点,查到键值对(20,地址),这表示小于20的记录在地址指向的下一层叶子节点中。接着根据下一层地址就可以找到最左边的叶子节点,在叶子节点中根据二分查找就能找到索引键值为5的记录。

那一个高度为2的B+树索引,理论上最多能存放多少行记录呢?

在 MySQL InnoDB存储引擎中,一个页的大小为16K,在上面的表User中,键值userId是BIGINT类型,则:

根节点能最多存放以下多个键值对 = 16K / 键值对大小(8+6) ≈ 1100

再假设表User中,每条记录的大小为500字节,则:

叶子节点能存放的最多记录为 = 16K / 每条记录大小 ≈ 32

综上所述,树高度为 2 的 B+ 树索引,最多能存放的记录数为:

总记录数 = 1100 * 32 =  35,200

也就是说,35200条记录排序后,生成的B+树索引高度为2。在35200条记录中根据索引键查询一条记录只需要查询2个页,一个根叶,一个叶子节点,就能定位到记录所在的页。

高度为3的B+树索引本质上与高度2的索引一致,如下图所示,不再赘述:

同理,树高度为3的 B+ 树索引,最多能存放的记录数为:

总记录数 = 1100(根节点) * 1100(中间节点) * 32 =  38,720,000

讲到这儿,你会发现,高度为3的B+树索引竟然能存放3800W条记录。高度为4的B+树索引就能存放上百亿的记录了,也就意味着在亿级别的数据中查询一条记录,只需要查询4页,也就是4次IO操作。那么B+树索引的优势是否逐步体现出来了呢?

不过,在真实环境中,每个页其实利用率并没有这么高,还会存在一些碎片的情况。

优化B+树索引的插入性能

B+树的查询高效是要付出代价的,也就是在插入时会带来性能问题。

B+ 树在插入时就对要对数据进行排序,但排序的开销其实并没有你想象得那么大,因为排序是CPU操作(当前一个时钟周期CPU能处理上亿指令)。

真正的开销在于B+树索引的维护,保证数据排序,这里存在两种不同数据类型的插入情况。

  • 数据顺序(或逆序)插入: B+ 树索引的维护代价非常小,叶子节点都是从左往右进行插入,比较典型的是自增 ID 的插入、时间的插入(若在自增 ID 上创建索引,时间列上创建索引,则 B+ 树插入通常是比较快的)。

  • 数据无序插入: B+ 树为了维护排序,需要对页进行分裂、旋转等开销较大的操作,另外,即便对于固态硬盘,随机写的性能也不如顺序写,所以磁盘性能也会收到较大影响。比较典型的是用户昵称,每个用户注册时,昵称是随意取的,若在昵称上创建索引,插入是无序的,索引维护需要的开销会比较大。

你不可能要求所有插入的数据都是有序的,因为索引的本身就是用于数据的排序,插入数据都已经是排序的,那么你就不需要B+树索引进行数据查询了。

所以对于B+树索引,在 MySQL 数据库设计中,仅要求主键的索引设计为顺序,比如使用自增,而不用无序值做主键。

MySQL中的B+树索引结构相关推荐

  1. mysql中b树索引_Mongo和Mysql中的B树索引

    为什么Mysql中Innodb的索引结构采取B+树? 回答这个问题时,给自己留一条后路,不要把B树喷的一文不值.因为网上有些答案是说,B树不适合做文件存储系统的索引结构.如果按照那种答法,自己就给自己 ...

  2. Mysql 索引 总结 —— 概述 || 索引优势劣势|| 索引结构(索引是在MySQL的存储引擎层中实现的)|| BTREE 结构||B+TREE 结构||MySQL中的B+Tree||索引分类

    索引概述 MySQL官方对索引的定义为:索引(index)是帮助MySQL高效获取数据的数据结构(有序). 在数据之外,数据库系统还维护者满足特定查找算法的数据结构, 这些数据结构以某种方式引用(指向 ...

  3. mysql默认存储引擎的索引结构是_InnoDB引擎的索引和存储结构

    在Oracle 和SQL Server等数据库中只有一种存储引擎,所有数据存储管理机制都是一样的. 而MySql数据库提供了多种存储引擎.用户可以根据不同的需求为数据表选择不同的存储引擎,用户也可以根 ...

  4. mysql中创建视图、索引

    数据库的三级模式两级映射: 存储文件------>基本表----->视图 内模式   ------->模式   ------>外模式 一.视图 1.什么是视图: 视图是从一个或 ...

  5. MySQL(InnoDB剖析):24---B+树索引(聚集索引与非聚集索引(辅助索引))、B+树索引的分裂

    一.B+树索引概述 B+树索引的本质就是B+树在数据库中的实现.但是B+索引在数据库中有一个特点就是高扇出性,因此在数据库中,B+树的高度一般都在2~4层,也就是说查找某一键值的行记录最多只需要2~4 ...

  6. MySQL(InnoDB剖析):---B+树索引(聚集索引与非聚集索引(辅助索引))、B+树索引的分裂

    小伙伴们大家好!今天是大年三十,给大家拜个早年!在此小弟祝各位大哥们与家人团团圆圆,和和睦睦,新的一年身体健康,工作顺利! 一.B+树索引概述 B+树索引的本质就是B+树在数据库中的实现.但是B+索引 ...

  7. MySQL中一个B+树能存储多少数据

    MySQL聚簇索引的存储结构 MySQL中InnoDB页的大小默认是16k.也可以自己进行设置.(计算机在存储数据的时候,最小存储单元是扇区,一个扇区的大小是 512 字节,而文件系统(例如 XFS/ ...

  8. MySQL中InnoDB引擎对索引的扩展

    摘要:InnoDB引擎对索引的扩展,自动追加主键值及其对执行计划的影响. MySQL中,使用InnoDB引擎的每个表,创建的普通索引(即非主键索引),都会同时保存主键的值. 比如语句 CREATE T ...

  9. mysql 创建表格time类型_记一次关于 Mysql 中 text 类型和索引问题引起的慢查询的定位及优化...

    最近有用户反馈产品有些页面加载比较慢,刚好我在学习 Mysql 相关知识,所以先从 Mysql 慢查询日志开始定位: step1:通过慢查询日志定位具体 SQL 首先通过 SHOW VARIABLES ...

  10. mysql 转成树_Mysql树型结构2种方式及相互转换

    Mysql实现树型结构,数据库上常见有2种方式:领接表.预排序遍历树(MPTT). 领接表方式-- 主要依赖于一个 parent 字段,用于指向上级节点,将相邻的上下级节点连接起来,id 为自动递增自 ...

最新文章

  1. SQLSERVER2014中的新功能
  2. go语言web开发框架_Iris框架讲解(六):Session的使用和控制
  3. 网站付费免费推广你更中意哪一个?
  4. THE TOP FILE(top文件详解)
  5. POJ 3268 (dijkstra算法)
  6. java椭圆 类_java 椭圆算法
  7. 个人所得税的申报方式有两种,分别有什么区别?该怎么选?
  8. 2022年PMP培训机构如何挑选?哪家好?
  9. java日期计算天数_Java 两个日期间的天数计算
  10. 华为最终面试java_最全的华为面试题-java学习
  11. 智慧城市建设中 网络安全攻防战如何打赢?
  12. 百度知道APP心跳包分析-MD5字段(gzip + CRC32)
  13. 阿里技术类面试真题,你能做对几个?(含答案)
  14. 1001: 植树问题
  15. 使用Python出现的错误和解决方法
  16. windows下的300个免费软件
  17. 【Android-I】Android开发之常见错误:Dx unsupported class file version 52.0...while parsing com/...
  18. 使用决策树(decision-tree)预测隐形眼镜类型(标签二值化(LabelBinarizer)复原输出)
  19. 人工智能领域有哪些优秀的工作第一次是被拒稿的,被什么拒了。现在怎么样? 拒稿理由是什么?...
  20. 企服网:电销外呼系统线路和系统哪个更重要?

热门文章

  1. 2021年AR/VR创企融资39亿美元创纪录 元宇宙成为推手
  2. 清除html宏病毒,手动清除EXCEL宏病毒的方法
  3. mac的鼠标滚动方向和触摸板方向,一个插件搞定
  4. 在自己电脑上无法用Foxmail客户端登录126邮箱的解决办法
  5. 稻盛和夫:中国企业如何在萧条中实现大飞跃
  6. C语言中不同类型之间的混合运算
  7. C语言—各种数据类型间的混合运算
  8. 通过Java 画一个太极图
  9. NodeJS启动vue项目的坑
  10. 调用百度地图API去掉地图左下角的百度LOGO方法