B-Tree / B+Tree 结构以及MySQL索引

对MySQL的索引相关的问题以前一直很不清楚,最近了解了下树和索引之间的关系,对这方面有了新的认识,感觉豁然开朗,留下一些笔记。

  • B-树

B-树不一定是二叉树,B树是一种平衡树,它的高度是固定的;
B树是一种多路查找树,也就是说它的节点上有多个存储的值;

BTree每个节点存储的数据量很大,可以算一算,每个节点的数据如果为100个,层高M为3,则总的数据量,将近似为:(1000+1)^3 - 1;这将超过10亿个。
然而,最多只需要3次磁盘IO就能读取到需要的数据到内存中。
相比于二叉树,它的优势在于它在查找的时候,每次能排除更多的无效数据,如果我们只需要查找一个数,二叉树每次只能排除1/2的无效数据,而上面提到的那棵BTree每次能排除1000/10001的数据。

BTree牺牲的是内存存储和计算,用此来换取更少的磁盘IO次数。
定义规则:
一棵M阶(M>=3)的B树,是一棵平衡的M路搜索树。它或者是空树,或者是满足下列性质的树:
1、根节点至少有两个子女;
2、每个非根节点所包含的关键字个数满足:[M/2 -1, M-1];(如果M为3,则每个非根节点上的关键字为[0,2],最多两个)
3、每个非根节点的出度正好是关键字总数+1 ;也就是说,3个关键字,将会有4个孩子,这3个关键字正好是4个孩子持有关键字的分界线;如图所示,这是一颗B+树的一部分:
这里写图片描述
关键字:30和40,将他们的三个子节点分为3段,每段都是按顺序排列的

4、所有的叶子都位于同一层;
5、每个节点的关键字都是按从小到大的顺序排列,

可以认为每个节点的所有数据都是一个连续的磁盘块,因为它是一次从磁盘中读取的,
每个节点有两部分数据:关键字 + 子节点指针;
每个节点的关键字个数是可以不一致的,只要满足条件就可以;

BTree的插入操作:
1、查找这个插入的数据是否已经存在,如果存在,则返回;
2、如果不存在,则将数据放在节点的顺序排列位置;
3、如果放置数据的节点的关键字个数已经满了,就将中间位置的数据往父节点的关键字部分添加;
4、如果父节点的关键字个数已经满了,就重复步骤3;

因为约束了根节点最少2个子节点,意思就是说根节点至少有一个关键字,树的高度不会变化;

- B+树
B+树是B树的一种变体,也是一种多路搜索树,它有如下更多的约束:
1、非叶子节点的子树指针与关键字个数相同;
2、非叶子节点的子树指针P[X],指向关键字属于[k[X],k[i+1])的子树;
3、只有叶子节点的关键字才是真正的数据
4、所有叶子节点都有一个链指针;
5、所有叶子节点都在同一层;
这里写图片描述(只是一部分)

  • 应用
    B树和B+树经常被运用到数据库中,作为MySQL的数据库索引。
    首先需要明确,索引是用来快速定位目标数据的;
    一个简单的SQL:select name from t_a where id = 20;
    首先从from语句开始解析,准备数据,从t_a表中取出id = 20的数据;然后再从数据中选择name字段;

如果id字段没有增加索引,就需要从开始到最后全部读出来,然后判断id是不是20,直到找到为止;
如果id字段增加了索引,则就会从承载索引的那颗B+树中找到id=20的节点,而后再定位到表数据;
哪种方式快?
不言而喻,第二种方式当然会比第一种要快,因为B+树的查找比起线性表,是快很多的;

关于MySQL的索引:
1、当定义一个主键时,MySQL的存储引擎把它当做一个聚集索引;
2、如果没有定义主键,则MySQL定位到第一个唯一索引,且该索引的所有列值均为非空的,则将其当做聚集索引;
3、如果没有主键或者适合做唯一索引,MySQL会生成一个隐藏的行ID值(6字节);
4、一个表中除了聚集索引,定义的都是辅助索引,也称为二级索引。

MySql的两套引擎,MyISAM和InnoDB,他们对索引的处理,有些差异;
MyISAM:
这里写图片描述
B+树叶子节点存储的是数据行的起始地址; 索引和数据是分开存的;
InnoDB 主索引:
这里写图片描述
InnoDB的数据和索引是放一起的;但是它的辅助索引,也是如此;所以MySQL的.ibd文件中,存储了表数据和索引信息;
了解完上面这些之后,一些关于InnoDB索引的问题,就有些眉目了:
1、一次查询只能用到一个索引;
因为索引是分开存的,不同的索引对应不同的数据;

2、尽量使用区分度高的列作为索引;
这很明显,区分度高,更有利于在树中的查找;

3、索引列不能参与计算;
索引列中保存的是表中的字段值,如果进行查找时还需要先把字段进行计算,开销太大;所以索引列做了函数操作之后,是不会走索引的;not、<>、!=亦是如此;

4、为什么索引越多,插入更新操作越慢?
索引越多,B+树越多,维护起来越费劲;

-EOF-

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值