mysql与B树那些事

二叉排序树

1.定义:

若左子树不空,则左子树上所有节点的值均小于它的根节点的值

若右子树不空,则右字数上所有节点的值均大于它的根节点的值

它的左、右子树也分别为二叉排序数(递归定义)

  1. 优点:,二叉排序树组织数据时,用于查找是比较方便的,因为每次经过一次节点时,最多可以减少一半的可能,不过极端情况会出现所有节点都位于同一侧,直观上看就是一条直线,那么这种查询的效率就比较低了,
  2. 平衡二叉树它的左子树和右子树的高度之差绝对值小于1,这样就不会出现一条支路特别长的情况。于是,在这样的平衡树中进行查找时,总共比较节点的次数不超过树的高度,这就确保了查询的效率(时间复杂度为O(logn)

B树

B树事实上是一种平衡的多叉查找树也就是说最多可以开m个叉(m>=2),我们称之为m阶b树

m阶B树满足以下条件:

1、每个节点至多可以拥有m棵子树

2、根节点,只有至少有2个节点(要么极端情况,就是一棵树就一个根节点,单细胞生物,即是根,也是叶,也是树)。

3、非根非叶的节点  至少有的Ceil(m/2)个子树(Ceil表示向上取整,图中5阶B树,每个节点至少有3个子树,也就是至少有3个叉)

4、非叶节点中的信息包括[n,   A0,K1,   A1,K2,A2,…,Kn,An],,其中n表示该节点中保存的关键字个数K为关键字且Ki<Ki+1,A为指向子树根节点的指针

从根到叶子的每一条路径都有相同的长度,也就是说,叶子节在相同的层,并且这些叶子节点不带信息

实际上这些节点就表示找不到指定的值,也就是指向这些节点的指针为空????????

 

B树的查询过程和二叉排序树比较类似,从根节点依次比较每个结点,因为每个节点中的关键字和左右子树都是有序的,所以只要比较节点中的关键字,或者沿着指针就能很快地找到指定的关键字

如果查找失败,则会返回叶子节点,即空指针?????

如果在非叶子节点上的关键字等于给定值,就终止;

可能B树的叶子结点就为空,只不过上图没有画出来????

 

例如查询图中字母表中的K

从根节点P开始,K的位置在P之前,进入左侧指针

左子树中,依次比较C、F、J、M,发现K在J和M之间

沿着J和M之间的指针,继续访问子树,并依次进行比较,发现第一个关键字K即为指定查找的值

B+树

作为B树的加强版,B+树与B树的差异在于

1、有n棵子树的节点含有n个关键字(也有认为是n-1个关键字)

2、所有的叶子节点包含了全部的关键字(定义的索引)及指向包含含这些关键字记录的指针且叶子节点本身根据关键字自小而大顺序连接

3、非叶子节点可以看成索引部分,节点中仅含有其子树(根节点)中的最大(或最小)关键字

B+树的查找过程,与B树类似,只不过查找时,如果在非叶子节点上的关键字等于给定值,并不终止,而是继续沿着指针直到叶子节点位置

因此在B+树,不管查找成功与否,每次查找都是走了一条从根到叶子节点的路径

mysql是如何使用B树的:

说明:事实上,在MySQL数据库中,诸多存储引擎使用的是B+树,即便其名字看上去是BTREE。

说明:事实上,在MySQL数据库中,诸多存储引擎使用的是B+树,即便其名字看上去是BTREE。

1、 innodb的索引机制

先以innodb存储引擎为例,说明innodb引擎是如何利用B+树建立索引的

首先创建一张表:zodiac,并插入一些数据


3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

CREATE TABLE `zodiac` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `name` char(4) NOT NULL,

  PRIMARY KEY (`id`),

  KEY `index_name` (`name`)

); 

 

insert zodiac(id,name) values(1,'鼠');  

insert zodiac(id,name) values(2,'牛');  

insert zodiac(id,name) values(3,'虎');  

insert zodiac(id,name) values(4,'兔');  

insert zodiac(id,name) values(5,'龙');  

insert zodiac(id,name) values(6,'蛇');  

insert zodiac(id,name) values(7,'马');  

insert zodiac(id,name) values(8,'羊');  

insert zodiac(id,name) values(9,'猴');

insert zodiac(id,name) values(10,'鸡');  

insert zodiac(id,name) values(11,'狗');  

insert zodiac(id,name) values(12,'猪');

 

 

 

 

对于innodb来说,只有一个数据文件  (    如果不创建索引的话,主索引文件就是innodb的数据文件),       

这个数据文件本身就是用B+树形式组织B+树每个节点的关键字就是表的主键,因此innode的数据文件本身就是主索引文件,如下图所示,主索引中的叶子页(leaf page)包含了数据记录,但非叶子节点只包含了主键

术语“聚簇”表示数据行(   这一行的数据   )和相邻的键值(    如果为主键,则为id   )紧凑地存储在一起,因此这种索引被称为聚簇索引,或聚集索引。

 

 

同样innodb的辅助索引如果设置索引时如下图所示---设置“鼠”,“牛”...为索引  ,假设这些字符是按照生肖的顺序排列的(其实我也不知道具体怎么实现,不要在意这些细节,就是举个例子),非叶子结点的关键字是“生肖的名字”其叶子节点中也包含了记录的主键因此innodb引擎在查询辅助索引的时候会查询两次,首先通过辅助索引得到主键值,然后再查询主索引

---举例:按名字查找“鼠”:

  1. 首先在辅助索引树中  按照关键字为“鼠”查找叶子结点:【鼠,1】,得到主键索引1
  2. 去主索引树根据主键索引1  查找整条记录 : 【1,鼠,小偷】

  1. innodb辅助索引的叶子结点存储的是主键值,这样的策略减少了当出现行移动或者数据页分裂时辅助索引的维护工作
  2. Innodb 存储引擎,叶子结点保存的是数据记录;当插入数据时,如果主键的值有序,则会把每一条记录都存储在上一条记录后面如果主键使用uuid,这样插入数据时innodb无法简单地将新数据插入到最后一行,降低了性能

myisam的索引机制:

注意:myisam没有自增

MyISAM引擎同样也使用B+树组织索引,如下图所示,假设我们的数据不是按照之前的顺序插入的,而是按照图中的是顺序插入表,insert into ..  vlaues(4,shu),(8,yang),(9,hou)........4,8是id

可以看到MyISAM引擎下,

 B+树叶子节点中包含的是数据记录的地址(可以简单理解为“行号”) 

而MyISAM的辅助索引在结构上和主索引没有本质的区别,同样其叶子节点也包含了数据记录的地址,稍微不同的是辅助索引的关键字是允许重复 .

myisam主索引和辅助索引的叶子结点存储的是地址,一旦发生行移动时,需要进行维护;

比较:

1.Innodb辅助索引的叶子节点存储的不是地址,而是主键值,这样的策略减少了当出现行移动或者数据页分裂时辅助索引的维护工作,虽然使用主键值当作指针会让辅助索引占用更多空间,但好处是,Innodb在移动行时无需更新辅助索引中的主键值,而MyISAM需要调整其叶子节点中的地址

满意请点赞,谢谢。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值