B树(B-Tree)的由来、数据结构、基本操作以及数据库索引的应用
B树是为磁盘存储而专门设计的一类平衡搜索树,B树的高度仅随着它所包含的节点数按对数增长,不过因为单个节点可以包含多个关键字,所以对数的底数可以比较大,实际应用中一般是50~2000,给个直观的数字,一棵分支因子为1001、高度为2(不包含根节点)的B树,可以存储超过10亿个关键字!
1.从磁盘结构讲起
计算机的机械磁盘,为了摊还机械移动花费的等待时间,磁盘会一次存取多个数据项而不是一个,这样的一次读取的信息单元是page,我们可以用读或写的页数作为磁盘存取总时间的主要近似值,在任何时刻,B树算法都只需在内存中保持一定数量的页面。B树的设计考虑磁盘预读取这点,一个B树的节点通常和一个完整磁盘页(page)一样大,并且磁盘页的大小限制了一个B树节点可以含有的孩子个数(分支因子),当然这个具体也需要取决于一个关键字相对一页的大小。B+ Tree中内部节点只存放关键字和孩子的指针,不存其他satellite information,因此最大化了内部节点的分支因子。
2.B树的数据结构
typedef int KeyType;
#define m 3
struct Node{
int keynum; /* 结点中关键字的个数,即结点的大小*/
struct Node *parent; /*指向parent结点*/
KeyType key[m]; /*关键字向量*/
struct Node *ptr[m]; /*子树指针向量*/
};

3.B树的查找
搜索一棵B树和搜索一棵二叉搜索树很相似,只是在每个节点所做的不是二叉或者“两路”分支选择,而是根据根节点的孩子数做多路分支选择。
4.B树的插入
B树插入的时候都是插入到叶节点上,插入的时候会从根节点开始顺着叶节点的方向沿途,如果遇到一个满节点(该节点上的关键字达到2t-1,t代表t阶B树),就会split该节点,分裂节点方式就是把满节点上的中间关键字往根节点方向提,分裂是树长高的唯一途径。B树的每个叶节点具有相同的高度,所以B树高度的增加发生在顶部而不是底部。插入节点的时候,从根的方向往下判断,如果不是叶子节点,则必须选择适当的叶子节点插入,因为在沿途已经分裂了节点,所以保证不会在满节点上再插入节点。
5.B树的删除
和插入关键字类似,插入关键字的时候要保证节点不会太大,而且有可能会增高B树。删除节点的时候要保证一个节点不会变得太小,因为B树的节点上的关键字有下界要求(除了根节点以外的每个内部节点至少有t个孩子,如果树非空,根节点上至少有一个关键字),删除关键字的时候如果在叶子节点,而且删除之后还满足B树的要求,那直接删除即可,不过如果是其他情况,比如在内部节点上删除关键字,那就有一系列的算法分支需要考虑,感兴趣的读者可以自行找资料慢慢琢磨了。不过在实际场景中,由于一棵B树中大部分关键字都在叶节点中,删除操作最经常是从叶子节点中删除关键字。
6.B树的应用场景
mysql的MyISAM和InnoDB两个存储引擎的索引实现方式:
- MyISAM引擎使用B+ Tree作为索引结构,叶节点存放的是数据记录的地址。
- MyISAM引擎的辅助索引(二级索引)和主索引在结构上没有区别,只是辅助索引的key可以重复,叶节点上存放的也是数据记录的地址。
- MyISAM索引文件和数据文件是分离的,索引文件仅保存数据记录的地址。
- InnoDB中表数据本身就是按B+ Tree组织的一个索引结构,叶节点存放的就不是数据记录的地址,而是完整的数据记录。所以InnoDB这种存储方式,又称为聚集索引,使得按主键的搜索十分高效,但二级索引搜索需要检索两遍索引:首先二级索引获得主键,然后用主键到主索引中检索到数据记录。
- 因为主键是InnoDB表记录的”逻辑地址“,所以InnoDB要求表必须有主键,MyISAM可以没有。
B树(B-Tree)的由来、数据结构、基本操作以及数据库索引的应用的更多相关文章
- 线段树 Interval Tree
一.线段树 线段树既是线段也是树,并且是一棵二叉树,每个结点是一条线段,每条线段的左右儿子线段分别是该线段的左半和右半区间,递归定义之后就是一棵线段树. 例题:给定N条线段,{[2, 5], [4, ...
- 数据结构之树(Tree)(一) :树
ps:好久没用动手写blog了,要在这条路上不断发展,就需要不停的学习,不停的思考与总结,当把写blog作为一种习惯,就是自我成长的证明,Fighting!. 一.简介 树是一种重要的非线性数据结构, ...
- Linux 内核中的数据结构:基数树(radix tree)
转自:https://www.cnblogs.com/wuchanming/p/3824990.html 基数(radix)树 Linux基数树(radix tree)是将指针与long整数键值相 ...
- Python入门篇-数据结构树(tree)的遍历
Python入门篇-数据结构树(tree)的遍历 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.遍历 迭代所有元素一遍. 二.树的遍历 对树中所有元素不重复地访问一遍,也称作扫 ...
- Python入门篇-数据结构树(tree)篇
Python入门篇-数据结构树(tree)篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.树概述 1>.树的概念 非线性结构,每个元素可以有多个前躯和后继 树是n(n& ...
- 数据结构 B-树和B+树的应用:数据搜索和数据库索引
B-树 1 .B-树定义 B-树是一种平衡的多路查找树,它在文件系统中很有用. 定义:一棵m 阶的B-树,或者为空树,或为满足下列特性的m 叉树:⑴树中每个结点至多有m 棵子树:⑵若根结点不是叶子结点 ...
- K:伸展树(splay tree)
伸展树(Splay Tree),也叫分裂树,是一种二叉排序树,它能在O(lgN)内完成插入.查找和删除操作.在伸展树上的一般操作都基于伸展操作:假设想要对一个二叉查找树执行一系列的查找操作,为了使 ...
- 基数树(radix tree)
原文 基数(radix)树 Linux基数树(radix tree)是将指针与long整数键值相关联的机制,它存储有效率,并且可快速查询,用于指针与整数值的映射(如:IDR机制).内存管理等.ID ...
- 『线段树 Segment Tree』
更新了基础部分 更新了\(lazytag\)标记的讲解 线段树 Segment Tree 今天来讲一下经典的线段树. 线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间 ...
随机推荐
- jquery 将disabled的元素置为enabled的三种方法
转--http://www.jb51.net/article/19342.htm 在jquery中可以通过jqueryObj.attr("disabled","disab ...
- [分类算法] :朴素贝叶斯 NaiveBayes
1. 原理和理论基础(参考) 2. Spark代码实例: 1)windows 单机 import org.apache.spark.mllib.classification.NaiveBayes im ...
- gulp复制整个文件夹或文件到指定目录(包括拷贝单个文件)
整个目录: gulp.task('copy', function() { return gulp.src('src/**/*') .pipe(gulp.dest('dist')) }); gulp拷贝 ...
- Java面试之SpringMVC总结以及在面试中的一些问题.
1.简单的谈一下SpringMVC的工作流程? 流程 1.用户发送请求至前端控制器DispatcherServlet 2.DispatcherServlet收到请求调用HandlerMapping处理 ...
- 查找树ADT——二叉搜索树
在以下讨论中,虽然任意复杂的关键字都是允许的,但为了简单起见,假设它们都是整数,并且所有的关键字是互异的. 总概 使二叉树成为二叉查找树的性质是,对于树中的每个节点X,它的左子树中所有关键字值小于 ...
- FireFox每次访问页面时检查最新版本
FireFox每次访问页面时检查最新版本 浏览器都有自己的缓存机制,作为开发人员,每次js的修改都要清空缓存,显然很不方便.而firefox并没有提供ie那样的设置. 下面的方法就可以非常方便的设置f ...
- [UML]UML系列——类图class的依赖关系
相关文章 [UML]UML系列——用例图Use Case [UML]UML系列——用例图中的各种关系(include.extend) [UML]UML系列—— ...
- ORACLE 触发器
•1.1 触发器类型 • DML触发器 • 替代触发器 • 系统触发器 •1.2 创建触发器 • 触发器触发次序 • 创建DML触发器 • 创建替代(INSTEAD OF)触发器 • 创建系统事件触发 ...
- hive单机安装(实战)
hive使用与注意事项:http://blog.csdn.net/stark_summer/article/details/44222089 连接命令:beeline -n root -u jdbc: ...
- UI第八节——UISegmentedControl
- (void)viewDidLoad { [super viewDidLoad]; NSArray *items = @[@"消息", @"电话" ...