B树(又叫平衡多路查找树)

注意B-树就是B树,-只是一个符号。

B树的性质(一颗M阶B树的特性如下)

1、定义任意非叶子结点最多只有M个儿子,且M>2; 
2、根结点的儿子数为[2, M]; 
3、除根结点以外的非叶子结点的儿子数为[M/2, M]; 
4、每个结点存放至少M/2-1(取上整)和至多M-1个关键字;(至少2个关键字) 
5、非叶子结点的关键字个数=指向儿子的指针个数-1; 
6、非叶子结点的关键字:K[1], K[2], …, K[M-1];且K[i] < K[i+1]; 
7、非叶子结点的指针:P[1], P[2], …, P[M];其中P[1]指向关键字小于K[1]的子树,P[M]指向关键字大于K[M-1]的子树,其它P[i]指向关键字属于(K[i-1], K[i])的子树; 
8、所有叶子结点位于同一层;

B-树的搜索,从根结点开始,对结点内的关键字(有序)序列进行二分查找,如果命中则结束,否则进入查询关键字所属范围的儿子结点;重复,直到所对应的儿子指针为空,或已经是叶子结点;

B-树的特性:

1.关键字集合分布在整颗树中;

2.任何一个关键字出现且只出现在一个结点中;

3.搜索有可能在非叶子结点结束;

4.其搜索性能等价于在关键字全集内做一次二分查找;

B+树

(1)简介

B+树是应文件系统所需而产生的一种B树的变形树(文件的目录一级一级索引,只有最底层的叶子节点(文件)保存数据)非叶子节点只保存索引,不保存实际的数据,数据都保存在叶子节点中,这不就是文件系统文件的查找吗?

我们就举个文件查找的例子:有3个文件夹a、b、c, a包含b,b包含c,一个文件yang.c,a、b、c就是索引(存储在非叶子节点), a、b、c只是要找到的yang.c的key,而实际的数据yang.c存储在叶子节点上。

所有的非叶子节点都可以看成索引部分!

(2)B+树的性质(下面提到的都是和B树不相同的性质)

1、非叶子节点的子树指针与关键字个数相同; 
2、非叶子节点的子树指针p[i],指向关键字值属于[k[i],k[i+1]]的子树.(B树是开区间,也就是说B树不允许关键字重复,B+树允许重复); 
3、为所有叶子节点增加一个链指针; 
4、所有关键字都在叶子节点出现(稠密索引). (且链表中的关键字恰好是有序的); 
5、非叶子节点相当于是叶子节点的索引(稀疏索引),叶子节点相当于是存储(关键字)数据的数据层; 
6、更适合于文件系统;

非叶子节点(比如5,28,65)只是一个key(索引),实际的数据存在叶子节点上(5,8,9)才是真正的数据或指向真实数据的指针。

应用  

1、B和B+树主要用在文件系统以及数据库做索引,比如MySQL;(MySQL使用B+树)

B/B+树性能分析

n个节点的平衡二叉树的高度为H(即logn),而n个节点的B/B+树的高度为logt((n+1)/2)+1; 
若要作为内存中的查找表,B树却不一定比平衡二叉树好,尤其当m较大时更是如此。因为查找操作CPU的时间在B-树上是O(mlogtn)=O(lgn(m/lgt)),而m/lgt>1;所以m较大时O(mlogtn)比平衡二叉树的操作时间大得多。因此在内存中使用B树必须取较小的m。(通常取最小值m=3,此时B-树中每个内部结点可以有2或3个孩子,这种3阶的B-树称为2-3树)。

为什么说B+树比B树更适合数据库索引?

1、 B+树的磁盘读写代价更低:B+树的内部节点并没有指向关键字具体信息的指针,因此其内部节点相对B树更小,如果把所有同一内部节点的关键字存放在同一盘块中,那么盘块所能容纳的关键字数量也越多,一次性读入内存的需要查找的关键字也就越多,相对IO读写次数就降低了。

2、B+树的查询效率更加稳定:由于非终结点并不是最终指向文件内容的结点,而只是叶子结点中关键字的索引。所以任何关键字的查找必须走一条从根结点到叶子结点的路。所有关键字查询的路径长度相同,导致每一个数据的查询效率相当。

3、由于B+树的数据都存储在叶子结点中,分支结点均为索引,方便扫库,只需要扫一遍叶子结点即可,但是B树因为其分支结点同样存储着数据,我们要找到具体的数据,需要进行一次中序遍历按序来扫,所以B+树更加适合在区间查询的情况,所以通常B+树用于数据库索引。

PS:我在知乎上看到有人是这样说的,我感觉说的也挺有道理的:

他们认为数据库索引采用B+树的主要原因是:B树在提高了IO性能的同时并没有解决元素遍历的我效率低下的问题,正是为了解决这个问题,B+树应用而生。B+树只需要去遍历叶子节点就可以实现整棵树的遍历。而且在数据库中基于范围的查询是非常频繁的,而B树不支持这样的操作或者说效率太低。

 
 

今天看了几篇文章,自己总结一下。

数据库使用B+树肯定是为了提升查找效率。

但是具体如何提升查找效率呢?

查找数据,最简单的方式是顺序查找。但是对于几十万上百万,甚至上亿的数据库查询就很慢了。

所以要对查找的方式进行优化,熟悉的二分查找,二叉树可以把速度提升到O(log(n,2)),查询的瓶颈在于树的深度,最坏的情况要查找到二叉树的最深层,由于,每查找深一层,就要访问更深一层的索引文件。在多达数G的索引文件中,这将是很大的开销。所以,尽量把数据结构设计的更为‘矮胖’一点就可以减少访问的层数。在众多的解决方案中,B-/B+树很好的适合。B-树定义具体可以查阅,简而言之就是中间节点可以多余两个子节点,而且中间的元素可以是一个域。相比B-树,B+树的父节点也必须存在于子节点中,是其中最大或者最小元素,B+树的节点只存储索引key值,具体信息的地址存在于叶子节点的地址中。这就使以页为单位的索引中可以存放更多的节点。减少更多的I/O支出。因此,B+树成为了数据库比较优秀的数据结构,MySQL中MyIsAM和InnoDB都是采用的B+树结构。不同的是前者是非聚集索引,后者主键是聚集索引,所谓聚集索引是物理地址连续存放的索引,在取区间的时候,查找速度非常快,但同样的,插入的速度也会受到影响而降低。聚集索引的物理位置使用链表来进行存储。

参考链接:

https://www.2cto.com/net/201808/773535.html

https://www.cnblogs.com/tiancai/p/9024351.html

MySQL数据库中索引的数据结构是什么?(B树和B+树的区别)的更多相关文章

  1. Mysql数据库中索引的概念总结

    1.索引的目的是什么 1.快速访问数据表中的特定信息,提高检索速度 2.创建唯一性索引,保证数据库表中每一行数据的唯一性. 3.加速表和表之间的连接 4.使用分组和排序子句进行数据检索时,可以显著减少 ...

  2. MySQL数据库之索引

    1 引言 在没有索引的情况下,如果要寻找特定行,数据库可能要遍历整个数据库,使用索引后,数据库可以根据索引找出这一行,极大提高查询效率.本文是对MySQL数据库中索引使用的总结. 2 索引简介 索引是 ...

  3. MySQL数据库中的索引(一)——索引实现原理

    今天我们来探讨一下数据库中一个很重要的概念:索引. MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构,即索引是一种数据结构. 我们知道,数据库查询是数据库的最主要 ...

  4. MySQL存储引擎的实际应用以及对MySQL数据库中各主要存储引擎的独特特点的描述

    MySQL存储引擎的实际应用以及对MySQL数据库中各主要存储引擎的独特特点的描述: 1.MySQL有多种存储引擎: MyISAM.InnoDB.MERGE.MEMORY(HEAP).BDB(Berk ...

  5. 从SQLSERVER/MYSQL数据库中随机取一条或者N条记录

    从SQLSERVER/MYSQL数据库中随机取一条或者N条记录 很多人都知道使用rand()函数但是怎麽使用可能不是每个人都知道 建立测试表 USE [sss] GO ,NAME ) DEFAULT ...

  6. mysql管理 ------查看 MySQL 数据库中每个表占用的空间大小

    如果想知道MySQL数据库中每个表占用的空间.表记录的行数的话,可以打开MySQL的 information_schema 数据库.在该库中有一个 TABLES 表,这个表主要字段分别是: TABLE ...

  7. MySQL数据库对象-索引

    1. 概述2. 索引分类2.1 不同索引的概念2.1.1 普通索引2.1.2 唯一索引2.1.3 全文索引2.1.4 多列索引3. 索引操作3.1 普通索引3.1.1 创建表时创建普通索引3.1.2 ...

  8. Mysql数据库中InnoDB和MyISAM的差别

    Mysql数据库中InnoDB和MyISAM的差别 InnoDB和MyISAM是在使用MySQL最常用的两个表类型,各有优缺点,视具体应用而定.基本的差别为:MyISAM类型不支持事务处理等高级处理, ...

  9. 千万级MySQL数据库建立索引,提高性能的秘诀

    实践中如何优化MySQL 实践中,MySQL的优化主要涉及SQL语句及索引的优化.数据表结构的优化.系统配置的优化和硬件的优化四个方面,如下图所示: SQL语句及索引的优化 SQL语句的优化 SQL语 ...

随机推荐

  1. 学术Essay写作中Introduction的正确打开方式

    其实在学术essay写作过程中,很多留学生经常不知道如何写introduction,所以有些开头的模板句就出现了,比如,With the development of society/With the ...

  2. 科学 multi port

    issues/679 create new UUID cat /proc/sys/kernel/random/uuid example config : multi port , multi user ...

  3. 2020/1/30 PHP代码审计之文件上传漏洞

    0x00 漏洞简介 文件上传漏洞是指用户上传了一个可执行的脚本文件,并通过此脚本文件获得了执行服务器端命令的能力.这种攻击是最为直接和有效的,"文件上传"本身是没有问题,有问题的是 ...

  4. APP中H5页面调试神器

    Fiddler Web Debugging Tool for Free by Telerik window 可以 下载,然后我的H5 嵌入到 APP 里面就可以快速捕捉到接口啦.不会因为看不见就得靠“ ...

  5. 【2017西安邀请赛:A】XOR(线段树+线性基)

    前言:虽然已经有很多题解了,但是还是想按自己的理解写一篇. 思路:首先分析题目 一.区间操作 —— 线段树 二.异或操作 —— 线性基 这个两个不难想,关键是下一步的技巧 “或”运算 就是两个数的二进 ...

  6. PAT Advanced 1066 Root of AVL Tree (25) [平衡⼆叉树(AVL树)]

    题目 An AVL tree is a self-balancing binary search tree. In an AVL tree, the heights of the two child ...

  7. E - Tokitsukaze and Duel CodeForces - 1190C (博弈 + 窗体移动)

    "Duel!" Betting on the lovely princess Claris, the duel between Tokitsukaze and Quailty ha ...

  8. postfix简单记录

    1.将/etc/postfix/main.cf编辑 myhostname和mydomain等 2.即可测试发送邮件 3.安装DNS功能,其中13和21行改成any yum install bind b ...

  9. java 单利模式设计原理,饿汉式懒汉式,开发中推荐饿汉式

    单例模式的设计:  1 //Single类进内存,对象还没有存在,只有调用了getInstance方法时,才建立对象. //对象是方法被调用时,才初始化,也叫做对象的延时加载.成为:懒汉式. //Si ...

  10. Java 二维数组,排序、切换顺序,查表法二进制十进制,这班查找、排序(冒泡、选择)、遍历,获取最大小值(4)

    Java 二维数组,排序.切换顺序,查表法二进制十进制,折半查找.排序(冒泡.选择).遍历,获取最大小值(4)