前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >B+树,索引树

B+树,索引树

作者头像
烟草的香味
发布2019-12-02 21:16:02
8570
发布2019-12-02 21:16:02
举报
文章被收录于专栏:烟草的香味烟草的香味

引言

时隔一年,我又想起当初看数据库时,看到的B+树,就是数据库的索引使用的数据结构。再整理一下,看看自己没有忘记很多吧。

概述

B+树之前,先来看一下二叉查找树(1,2,3,4,5,6,7)

恩, 差不多就长这样。诚然,在二叉查找树中查找某个元素是很快速的,二分查找嘛。但想想数据库查找数据的场景:

select * from user where id > 10, 显然,对于这种查找区间来说,二叉查找树并不高效。那么B+树是如何解决这个问题的呢?

试想一下,区间查找比较高效的数据结构是什么?数组,只要找到id为10的元素下标,那么之后的所有就都符合了。

那么把上面修改一下,让二叉查找树树的叶子节点直接指向数组的下标不就好了嘛。修改后结构如下:

这时,如果想找select * from user where id > 2 and id < 5, 那么,直接找到2的下标,然后向后遍历,到第一个>=5的值出现停止,之间是满足条件的数据。没错,这就是B+树。

这个结构是怎么想出来的我不知道啊,但是我今天突然发现,他的存储方式和跳表十分之像啊。莫非是受到了跳表的启发?亦或是跳表受到了B+树的启发?咱也不知道。

引申

很好,B+树整明白了,新的问题出现了。如果数据库使用这种数据结构存储,全部放到内存中肯定是不现实的,势必要将其存储到硬盘中,待查找时再到文件中读取。但如果放到文件中,势必会造成IO的缓慢,每次读取节点都访问文件,要是树到高度很夸张的话,光IO就要耗尽耐心了。

既然如此,那就降低IO好了,增加树每一层的节点数量,也就是二叉树变成n叉树(也确实是这么做的)。

算一下,如果是3叉树,高度为3(这个高度为索引树的高度),可索引的数组长度为:(3^4=81);如果是5叉树,高度为3,可索引数组长度为:(5^4=625);如果是100叉树,高度为3,可索引长度为:(100^4=1亿)。索引1亿的数据量,高度也只有3,意味着只要进行3此IO就可以定位到。完美。

那树进行分叉过多,是不是在每个节点搜索子节点的效率下降了?这里可以再使用一些查找算法降低时间复杂度。


以上就是我回忆的内容了,感觉并没有什么晦涩的,大部分是重新回忆了一遍。但是,温故而知新嘛。不知点新怎么好意思写出来。一下就是我最近才晓得的了。

B+树是不是分叉越多越好

那肯定不是越多越好啊,要是一层就把所有数据都存储了,要他还有什么用,根本没有起到快速定位的作用。

但我想说的并不是这。我们知道,操作系统在读取磁盘中的数据时,是按照页来读取和管理的,一页大小为4kb。当读取数据时,如果大小超过4kb,就会触发多次IO。4kb的大小,其实对于存储节点已经很大了。也就是说,我们每个节点的大小最好是<=4kb,否则就会触发多次IO。

但是,节点在更新时,势必会导致其大小改变。如何保证n叉树始终为n叉树呢?

添加节点

其实很简单,多了就拆呗。如果节点超出大小,就拆分成两个节点。但拆分后父节点不就多了么。那就父节点在拆,一直拆到根节点为止。如果根节点在超出大小,那就再拆,整个新的根节点出来。

删除节点

其实,删除节点不做处理也不会影响节点大小超出限制。但是,长此以往,可能会导致某些节点元素过少,严重影响查询效率。那么,如果节点内元素的数量小于n/2,就把相邻的两个节点合并为一个节点。那要是合并后元素数量超出大小呢?再拆呗。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-11-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 烟草的香味 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 引言
  • 概述
  • 引申
  • B+树是不是分叉越多越好
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档