B树和B+树

索引

先聊一下索引的作用 :更快的查询数据。

那么如何去设计一个索引呢?(用什么数据结构来实现?)

1、线性索引

        查询效率很慢(如查询线性末端的数据)

        插入和删除,数据移动带来巨大的成本。

2、hash索引

        hash冲突后,数据散列不均匀,还是会有大量线性查询,效率低(其实这个不是重点)

        等值查询时可以的,但是遇到范围查询,只能挨个查询了,还是导致了效率低下

3、二叉排序树 BST

        假设插入树时的顺序是按照从小到大或者从大到小插入的,二叉树就会退化成链式结构,又变成了线性查询

BST插入数据要保证:

        若左子树不为空,则左子树上面的所有节点值都要小于根节点的值

        若右子树不为空,则右子树上面的所有节点值都要大于根节点的值

4、平衡二叉树 AVL

        插入的成本来弥补查询的效率,但是对于插入删除操作比查询操作多的情况,不太合适。

        数据多,数的深度变深,查找次数也变多,IO效率也会降低

在BST树的基础上改进,加一个平衡因子,左子树和右子树 高度之差绝对值不大于1

可以看到,我们常见的数据结构都没办法满足适用于高效率查询索引,因此,就引入了B树,B树其实就是一个有序的多路查询树

B树

        前面讲到,AVL树在数据量很大的情况下,树的深度会变的很深,这也意味着查询时IO的次数会变多,读取的效率也会降低,那么,将AVL的二叉 改成多叉,是否就可以解决这个问题呢?

1、m阶(度)B树的定义:

  1. 树中每个节点至多有m个孩子节点
  2. 有m个孩子节点的非叶子节点有m-1个键,键按照递增顺序排列。
  3. 除根节点外,其他节点至少有m/2个孩子节点
  4. 若根节点不是叶子节点,则跟节点至少有两个孩子节点
  5. 所有叶子节点都在同一层上,即B树是所有节点的平衡因子均等于0的多路查找树。

2、每个节点的结构:

n代表这个节点上有几个值(键),k1~kn就是叶子节点上的键,p0~pn就是指针,指向孩子节点,还有一块data区域,就是该键对应的值(KV结构)

 

磁盘预读:

  • 内存和磁盘发生交互的时候,一般情况下有一个最小的逻辑单元,成为页,datapage
  • datapage由操作系统决定是多大,一般是4k或者8k,数据交互时,可以取页的整数倍来进行读取。

B树和B+树的区别?

  1. 相比于B树,B+树的非叶子节点不存储数据,而是把所有的关键码都储存在叶子节点(这个关键码我理解是两种:myISAM 中存储的是指向数据行的地址,innnoDB中存储的是数据行数据)
  2. B+叶子节点包含了全部关键码,叶子节点本身已经从小到大排好了序,并且叶子节点之间是有相互引用关系的
  3. 寻找数据时,B树可能不需要找到叶子节点就可以找到数据,而B+树则必须要走到叶子节点才可以。

聚集索引和非聚集索引

非聚集索引:例如myISAM,索引文件和数据文件是分离的,查找时,先从索引文件中找到对应元素相关数据行的磁盘文件地址,然后通过磁盘文件地址去数据文件中查找数据行。

聚集索引:例如InnoDB, 索引和数据放在一个文件中,查到时,找到对应的叶子节点后直接就可以得到数据行。

为什么说建议innoDB必须要有主键,并且推荐使用整型的自增型主键呢?

innoDB存储引擎的数据结构必须要一个主键才可以组织起来,用户使用innoDB储存引擎建表的时候,如果没有指定主键,则mysql会自动帮你找到一个合适的唯一索引作为主键,如果找不到符合唯一索引条件的字段时,会类似生成rowID的虚拟列当做innoDB的主键。--- 如果建表的时候定义了这个主键字段,innoDB会直接使用这个字段进行建表,进而减少了mysql帮你找主键或者建立新字段带来的性能损耗。

innoDB存储引擎建立索引时,使用的数据结构为B+tree,因为B+tree是有序的,因此在生成和后续查询时,都要对元素进行比较,整型的对比效率是高于其他数据结构(字符串等)

相邻的索引对应的数据也是相邻地存放在磁盘上,如果主键不是自增的,在存储过程中会不断的调整数据的物理地址、分页,带来效率上的降低,而自增的索引,只需要一页一页的存储就行了,索引结构相对紧凑,磁盘碎片少,效率也高。

为什么innoDB非主键索引结构叶子节点存储的是主键值?

一致性:数据库表进行大量DML操作的时候,同一行记录的页地址会发生变化,非主键索引因为保存的是主键的值,因此不需要额外的修改。

节省存储空间:innoDB数据本身就已经吧数据行都保存在主键索引的B+tree上了,如果其他索引还保存,会导致空间的浪费。

注意:myISAM主键和非主键索引保存的都是数据行的地址。

MyISAM通过索引查询的步骤

1、主键索引等值查询 --- 三次索引查询加一次记录数据查询

在这里插入图片描述

 2、主键索引范围查询  --- 四次索引查询加一次记录数据查询

在这里插入图片描述

 注意:MyISAM查询时,会将索引节点缓存在mysql的缓存中,因此并不是每次都会走磁盘IO

3、辅助索引查询

在 MyISAM 中,辅助索引和主键索引的结构是一样的,没有任何区别,叶子节点的数据存储的都是行记录的磁盘地址。只是主键索引的键值是唯一的,而辅助索引的键值可以重复

因此使用辅助索引,即便是等值查询,也要走范围查找

InnoDB通过索引查询的步骤

1、主键索引等值查询  --- 三次索引查询

在这里插入图片描述

 2、辅助索引查询

除聚簇索引之外的所有索引都称为辅助索引,InnoDB的辅助索引只会存储主键值而非磁盘地址,辅助索引需要检索两遍索引:首先检索辅助索引获得主键,然后使用主键到主索引中检索获得记录。 ---- 辅助索引三次查询 + 回表三次查询

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值