数据库学习(三)

四、聚集索引、非聚集索引
聚集索引:类似字典的拼音目录

  • 数据本身就是按照聚集索引的顺序存储的,应该建在需要频繁修改的列上,因为聚集索引的每次改动都以为这表中数据的物理数据的一次重新排序
  • 聚集索引适合建立在大数据量但是小数目不同值的列上
  • 聚集索引的修改一定一定一定要谨慎,因为聚集索引涉及要数据的物理存放数据,不合理的聚集索引会十分严重的拖累数据库的性能
  • 聚集索引找到符合条件的目标即获得该目标行的所有数据,因为直接找到是他的物理地址
  • 聚集索引值是允许重复的
  • 在这里插入图片描述
    非聚集索引:
  • 使用非聚集所引且要查询的列不包含非聚集索引列本身,那么要经过二次查询。一次查询获得聚集索引的key,二次通过key与聚集索引确定目标数据
  • 非聚集索引适合建立在大数据量下且有大数目不同值,即列中大部分值都互不相同的情况
  • 在这里插入图片描述
    使用场景:

在这里插入图片描述
五、B树与B+树

  二叉查找树的查找时间复杂度是O(logN)
B树和B+树的的出现是因为磁盘IO的问题,IO操作的效率很低,那么在大量数据存储中,查询时我们不能一下子将所有数据加载到内存中,只能逐一加载磁盘页,每个磁盘页对应树的节点。造成大量磁盘IO操作(最坏情况下树的高度)。平衡二叉树由于树深度过大而造成磁盘IO读写过于频繁,进而导致效率低下。所以为了减少磁盘IO次数,就必须降低树的深度:
1)每个节点存储多个元素
2)摒弃二叉树结构,采用多叉树

B树:

m阶的B树有以下几个特征:

  • B树中所有结点的孩子结点的最大值称为B树的阶,通常用m表示。
  • 一个结点有k个孩子时,必有K-1个关键字划分为k个子集
    1、根结点至少有两个子女
    2、每个中间结点都包含k-1个元素和k个孩子,其中ceil(m/2)<=k<=m
    3、每一个叶子结点都包含k-1个元素,其中ceil(m/2)<=k<=m
    4、所有的叶子结点都位于同一层
    5、每个结点中的元素从小到大排列,节点当中k-1个元素正好是k个孩子包含的元素的值域划分

三阶B树
在这里插入图片描述

查询:若查询数值为5:

第一次磁盘IO:在内存中定位(与17、35比较),比17小,左子树;
第二次磁盘IO:在内存中定位(与8、12比较),比8小,左子树;
第三次磁盘IO  : 在内存中定位(与3、5)比较,找到5,终止。
比较的次数并不比二叉树少,但是IO次数却大大减少。比较是在内存中进行的,相比于磁盘IO的速度,比较的耗时几乎可以省略,所以树的高度足够低的话,就可以极大的提高效率,节点的元素增多只是多了几次内存交互而已,只要不超过磁盘页的大小即可。

插入、删除:

对高度为K的m阶B树,新节点一般是插在叶子层。通过检索可以确定关键码应插入的结点位置,然后分情况讨论:
https://blog.csdn.net/z_ryan/article/details/79685072

注意:

  • B树主要用于文件系统以及部分数据库索引,例如:MongoDB。而大部分关系数据库则使用B+树做索引,例如:mysql数据库
  • 从查找效率考虑一般要求B树的阶树m>=3;
  • B-树上算法的执行时间主要由读、写磁盘的次数来决定,故一次I/O操作应读写尽可能多的信息。因此B-树的节点规模一般以一个磁盘页为单位。一个节点包含的关键字及其孩子个数取决于磁盘页的大小

B+树:

B+树是B树的变种,有着比B树更高的查询效率。

特点:

一个m阶的B+树具有如下几个特征:

  • 1.有k个子树的中间节点包含有k个元素(B树中是k-1个元素),每个元素不保存数据,只用来索引,所有数据 都保存在叶子节点。

    2.所有的叶子结点中包含了全部元素的信息,及指向含这些元素记录的指针,且叶子结点本身依关键字的大小 自小而大顺序链接。

    3.所有的中间节点元素都同时存在于子节点,在子节点元素中是最大(或最小)元素。
    下面是一棵3阶的B+树:
    在这里插入图片描述

B+树通常有两个指针,一个指向根结点,另一个指向关键字最小的叶子结点。因些,对于B+树进行查找两种运算:一种是从最小关键字起顺序查找,另一种是从根结点开始,进行随机查找。

查找

B+树的优势在于查找效率上,下面我们做一具体说明:
  首先,B+树的查找和B树一样,类似于二叉查找树。起始于根节点,自顶向下遍历树,选择其分离值在要查找值的任意一边的子指针。在节点内部典型的使用是二分查找来确定这个位置。
  (1)、不同的是,B+树中间节点没有卫星数据(索引元素所指向的数据记录),只有索引,而B树每个结点中的每个关键字都有卫星数据;这就意味着同样的大小的磁盘页可以容纳更多节点元素,在相同的数据量下,B+树更加“矮胖”,IO操作更少
  B树的卫星数据:
  在这里插入图片描述
  
  B+树的卫星数据:
  在这里插入图片描述
  
  需要补充的是,在数据库的聚集索引(Clustered Index)中,叶子节点直接包含卫星数据。在非聚集索引(NonClustered Index)中,叶子节点带有指向卫星数据的指针。
  
  (2)、其次,因为卫星数据的不同,导致查询过程也不同;B树的查找只需找到匹配元素即可,最好情况下查找到根节点,最坏情况下查找到叶子结点,所说性能很不稳定,而B+树每次必须查找到叶子结点,性能稳定
  (3)、在范围查询方面,B+树的优势更加明显
  B树的范围查找需要不断依赖中序遍历。首先二分查找到范围下限,在不断通过中序遍历,知道查找到范围的上限即可。整个过程比较耗时。
  而B+树的范围查找则简单了许多。首先通过二分查找,找到范围下限,然后同过叶子结点的链表顺序遍历,直至找到上限即可,整个过程简单许多,效率也比较高。
  例如:同样查找范围[3-11],两者的查询过程如下:
  B树的查找过程:
  在这里插入图片描述
  
  B+树的查找过程:
  在这里插入图片描述
 
插入

B+树的插入与B树的插入过程类似。不同的是B+树在叶结点上进行,如果叶结点中的关键码个数超过m,就必须分裂成关键码数目大致相同的两个结点,并保证上层结点中有这两个结点的最大关键码。

删除

B+树中的关键码在叶结点层删除后,其在上层的复本可以保留,作为一个”分解关键码”存在,如果因为删除而造成结点中关键码数小于ceil(m/2),其处理过程与B-树的处理一样。在此,我就不多做介绍了。

总结

B+树相比B树的优势:
  1.单一节点存储更多的元素,使得查询的IO次数更少;
  2.所有查询都要查找到叶子节点,查询性能稳定;
  3.所有叶子节点形成有序链表,便于范围查询。

作者:z_ryan
来源:CSDN
原文:https://blog.csdn.net/z_ryan/article/details/79685072
版权声明:本文为博主原创文章,转载请附上博文链接!

猜你喜欢

转载自blog.csdn.net/adzn1/article/details/86522442