目录
B+树只有叶节点存放数据,其余节点用来索引,而B-树是每个索引节点都会有Data域。
1、定义
索引是一种数据结果,帮助提高获取数据的速度
为了提高查找速度,有很多查询优化算法。但是每种查找算法都只能应用于特定数据结构之上。
索引就是数据库创建的满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据
2、索引数据结构
目前大部分数据库系统及文件系统都采用B Tree或其变种B+Tree作为索引结构
相关概念介绍
- B-树(B树):多路搜索树,每个结点存储M/2到M个关键字,非叶子结点存储指向关键字范围的子结点;所有关键字在整颗树中出现,且只出现一次,非叶子结点可以命中;
- B+树:在B-树基础上,为叶子结点增加链表指针,所有关键字都在叶子结点中出现,非叶子结点作为叶子结点的索引;B+树总是到叶子结点才命中;
- B*树:在B+树基础上,为非叶子结点也增加链表指针,将结点的最低利用率从1/2提高到2/3;
3、为什么使用B Tree(B+Tree)
红黑树也可用来实现索引,但是文件系统及数据库系统普遍采用B/+Tree,为什么?
一般来说,索引本身也很大,不可能全存内存,往往以索引文件的形式存在磁盘
(1)单节点能存储更多数据,使得磁盘IO次数更少。
(2)叶子节点形成有序链表,便于执行范围操作。
(3)聚集索引中,叶子节点的data直接包含数据;非聚集索引中,叶子节点存储数据地址的指针。
4、索引分类
1.普通索引index :加速查找
2.唯一索引
主键索引:primary key :加速查找+约束(不为空且唯一)
唯一索引:unique:加速查找+约束(唯一)
3.联合索引
-primary key(id,name):联合主键索引
-unique(id,name):联合唯一索引
-index(id,name):联合普通索引
5、聚集索引和非聚集索引
聚集索引和非聚集索引使用的都是B+树结构。
1、非聚集索引
非聚集索引的叶子节点为索引节点,但是有一个指针指向数据节点。
MyISAM是非聚集索引。
2、聚集索引
聚集索引叶子节点就是数据节点。
关于聚集索引,innodb会按照如下规则进行处理:
1,如果一个主键被定义了,那么这个主键就是作为聚集索引
2,如果没有主键被定义,那么该表的第一个唯一非空索引被作为聚集索引
3,如果没有主键也没有合适的唯一索引,那么innodb内部会生成一个隐藏的主键作为聚集索引,这个隐藏的主键是一个6个字节的列,改列的值会随着数据的插入自增。
innodb的普通索引,唯一索引,联合索引都是辅助索引,采用非聚集索引结构。InnoDB的所有辅助索引都引用主键作为data域。
聚集索引这种实现方式使得按主键的搜索十分高效,但是辅助索引搜索需要检索两遍索引:首先检索辅助索引获得主键,然后用主键到主索引中检索获得记录。
B+树只有叶节点存放数据,其余节点用来索引,而B-树是每个索引节点都会有Data域。
所以从Mysql(Inoodb)的角度来看,B+树是用来充当索引的,一般来说索引非常大,尤其是关系性数据库这种数据量大的索引能达到亿级别,所以为了减少内存的占用,索引也会被存储在磁盘上。
那么Mysql如何衡量查询效率呢?– 磁盘IO次数。 B-树/B+树 的特点就是每层节点数目非常多,层数很少,目的就是为了就少磁盘IO次数,但是B-树的每个节点都有data域(指针),这无疑增大了节点大小,说白了增加了磁盘IO次数(磁盘IO一次读出的数据量大小是固定的,单个数据变大,每次读出的就少,IO次数增多,一次IO多耗时),而B+树除了叶子节点其它节点并不存储数据,节点小,磁盘IO次数就少。这是优点之一。
另一个优点是: B+树所有的Data域在叶子节点,一般来说都会进行一个优化,就是将所有的叶子节点用指针串起来。这样遍历叶子节点就能获得全部数据,这样就能进行区间访问啦。在数据库中基于范围的查询是非常频繁的,而B树不支持这样的遍历操作。
B树相对于红黑树的区别
AVL 数和红黑树基本都是存储在内存中才会使用的数据结构。
在大规模数据存储的时候,红黑树往往出现由于树的深度过大而造成磁盘IO读写过于频繁,进而导致效率低下的情况。为什么会出现这样的情况,我们知道要获取磁盘上数据,必须先通过磁盘移动臂移动到数据所在的柱面,然后找到指定盘面,接着旋转盘面找到数据所在的磁道,最后对数据进行读写。磁盘IO代价主要花费在查找所需的柱面上,树的深度过大会造成磁盘IO频繁读写。根据磁盘查找存取的次数往往由树的高度所决定,所以,只要我们通过某种较好的树结构减少树的结构尽量减少树的高度,B树可以有多个子女,从几十到上千,可以降低树的高度。读盘的时间分布叫寻道时间,旋转延迟和传输时间,三者的时间是依次减少的
1.寻道时间: 磁头 从开始移动到数据所在 磁道 所需要的时间, 寻道时间越短,I/O操作越快,目前磁盘的平均寻道时间一般在3-15ms、当前服务器已经可达3ms了。
2.旋转延迟: 盘片旋转将请求数据所在 扇区 移至读写 磁头 下方所需要的时间, 旋转延迟取决于 磁盘转速、当前服务器已经可达15000rpm。
3.数据传输时间:完成传输所请求的数据所需要的时间。
数据库系统的设计者巧妙利用了磁盘预读原理,将一个节点的大小设为等于一个页,这样每个节点只需要一次I/O就可以完全载入。为了达到这个目的,在实际实现B-Tree还需要使用如下技巧:每次新建节点时,直接申请一个页的空间,这样就保证一个节点物理上也存储在一个页里,加之计算机存储分配都是按页对齐的,就实现了一个node只需一次I/O。
为什么不用hash
问题1:MySQL中存储索引用到的数据结构是B+树,B+树的查询时间跟树的高度有关,是log(n),如果用hash存储,那么查询时间是O(1)。既然hash比B+树更快,为什么mysql用B+树来存储索引呢?
答:一、从内存角度上说,数据库中的索引一般时在磁盘上,数据量大的情况可能无法一次性装入内存,B+树的设计可以允许数据分批加载。
二、从业务场景上说,如果只选择一个数据那确实是hash更快,但是数据库中经常会选中多条这时候由于B+树索引有序,并且又有链表相连,它的查询效率比hash就快很多了。
感谢:
1、https://www.cnblogs.com/wangzhongqiu/archive/2019/04/22/10728569.html