B+树
特点
- B+树构建是根据主键值进行排序构建的。
子上向下生长,根节点一直不变
- 所有真实数据项均放在叶子节点中,非叶子节点中存放数据项索引,只存放
键值和页号(页地址)
。 - 内节点数据项的唯一性,一个页至少有两个数据记录。
- 页内是使用单链表,页间使用双链表
- 树高度一般不超过四层
优点
- B+树对于
主键(排序键)的排序查找和范围查找速度非常快
,因为链表的数据结构。 - 按照B+树排列顺序,查询显示一定范围数据的时候,由于数据都是紧密相连,数据库不用从多个数据块中提取数据,所以节省了大量的io操作。
缺点
- 插入速度严重
依赖于插入顺序
,按照主键的顺序插入是最快的方式,否则将会出现页分裂,严重影响性能。 - 更新主键的代价很高,因为将会导致被更新的行移动。
聚簇索引和非聚簇索引
如果我们想以别的列作为搜索条件该怎么办呢?
答案:我们可以多建几棵B+树,不同的B+树中的数据采用不同的排序规则。比方说我们用c2列的大小作为数据页、页中记录的排序规则,再建一棵B+树(非聚簇索引),效果如下图所示:
非聚簇索引的叶子节点不再是所有数据,而是包括主键值和被搜索的列值
。通过被索引的值找到叶子节点后获取主键值,再通过聚簇索引找到目标数据项。
当非聚簇索引排序的值相同时,通常使用主键值加以区分排序,所以MySQL中的InnoDB,在非聚簇索引中至少包含主键值和被搜索的列值。
对比
- 聚簇索引的叶子节点存储的就是我们的
数据项
,非聚簇索引的叶子节点存储的是数据位置
。非聚簇索引不会影响数据表的物理存储顺序。 - 一个表
只能有一个聚簇索引
,因为只能有一种排序存储的方式,但可以有多个非聚簇索引
,也就是多个索引目录提供数据检索。 - 使用聚簇索引的时候,数据的查询效率高,但如果对数据进行插入,删除,更新等操作,效率会比非聚簇索引低。
关于二级索引:
二级索引访问需要两次索引查找,第一次通过非聚簇索引找到主键值,第二次根据主键值找到数据项.
哈希表和B+树
- 哈希表不能查找范围值
- 哈希无序
- 无法对单个或者多个进行查询
- 重复值多的话会降低效率
B树
特点
- 叶子节点和非叶子节点都存放数据项
- 本质还是在全域上进行二分查找
B+和B
- B+有k个孩子的节点就有k个关键字。也就是孩子数量=关键字数,而B树中,孩子数量=关键字数+1。
- B+非叶子节点的关键字也会同时存在在子节点中,并且是在子节点中所有关键字的最大(或最小),B树中非叶子节点关键值是叶子节点中值。
- B+非叶子节点仅用于索引,不保存数据记录,跟记录有关的信息都放在叶子节点中。而B树中,非叶子节点既保存索引,也保存数据记录。
- B+所有关键字都在叶子节点出现,叶子节点构成一个有序链表,而B树是按照叶子节点本身关键字从小到大顺序构建。造成在数据库范围查找时,B+树直接根据链表依次取出就行了,但是B树中只能查后继节点,比较繁琐。