数据库常见索引

1.什么是索引

数据库索引好比是一本书前面的目录,能加快数据库的查询速度。


2.索引的优缺点

优点:

 1.大大加快数据的检索速度

 2.创建唯一性索引,保证数据库表中每一行数据的唯一性

 3.加速表和表之间的连接

 4.在使用分组和排序子句进行数据检索时,可以显著减少查询中分组和排序的时间

缺点

1.索引需要占用数据表以外的物理存储空间

2.创建索引和维护索引要花费一定的时间

3.当对表进行更新操作时,索引需要被重建,这样降低了数据的维护速度

3.索引类型

(1)唯一索引:UNIQUE 

例如在学生表中给学号字段创建唯一索引:create unique index stusno on student(sno);

表明此索引的每一个索引值只对应唯一的数据记录,对于单列唯一性索引,这保证单列不包含重复的值。对于多了唯一性索引,保证多列值得组合不重复

(2)主键索引  primary key 即唯一+非空

数据库关系图中在给表定义主键将自动创建主键索引,该索引要求主键中的每个值都唯一且非空。

(3)聚集索引(又叫聚簇索引):cluster

在聚集索引中,表中行的物理顺序与键值的逻辑(索引)顺序相同。一个表只能包含一个聚集索引。如果某索引不是聚集索引,则表中行的物理顺序与键值得逻辑顺序不匹配。与非聚集索引相比,聚集索引通常提供更快的数据访问速度。


4.索引的实现原理

4.1 B树

oracle数据库索引中用B树 ,索引类型介绍:https://blog.csdn.net/wulex/article/details/79394072

  即二叉搜索树   

1.所有非叶子结点至多拥有两个儿子(left和right)

2.所有节点存储一个关键字

3.非叶子节点的左指针指向小于其关键字的子树,右指针指向大于其关键字的子树

如下图所示

     

B树搜索路径:

从根结点开始,如果查询的关键字与结点的关键字相等,则命中。否则,如果查询的关键字比结点关键字小,就进入左儿子,反之大则进入右儿子;如果左儿子或右儿子的指针为空,则报告找不到对应的关键字。

拿关键字28来举例,首先与根结点35比较,小则进入左儿子17,又与17比较,大则进入右儿子28,相等则命中。

       如果B树的所有非叶子结点的左右子树的结点数目均保持差不多(平衡),那么B树的搜索性能逼近二分查找;但它比连续内存空间的二分查找的优点是,改变B树结构(插入与删除结点)不需要移动大段的内存数据,甚至通常是常数开销;

如:

但B树在经过多次插入和删除后,有可能导致不同的结构:

右边的也是一个B树,但其搜索性能已经是线性的了;同样的关键字集合有可能导致不同的树结构索引;所以,使用B树还要考虑尽可能让B树保持左图的结构,和避免右图的结构,也就是所谓的“平衡”问题。

实际是哟经的B树都是在原B树的基础上加上平衡算法,即"平衡二叉树";如何保持B树结构分布均匀的平衡算法是平衡二叉树的关键;平衡算法是一种在B树中插入和删除结点的策略。常见的平衡二叉树有:AVLRBT(红黑树)Treap(树堆),Splay Tree(伸展树)。

      下面介绍下红黑树

红黑树是一种近似平衡的二叉查找树,它能够确保任何一个节点的左右子树的高度差不会查过二者中较低那个的一倍。具体来说,红黑树是满足如下条件的二叉查找树(binary search tree):

  1. 每个节点要么是红色,要么是黑色
  2. 根节点必须是黑色
  3. 红色节点不能连续(即红色节点的孩子和父亲都不能是红色)
  4. 对于每个节点,从该点至null(树尾端)的任何路径,都含有相同个数的黑色节点。

在树的结构发生改变时(插入或者删除操作),往往会破坏上述条件3或条件4,需要通过调整使得查找树重新满足红黑树的条件。

 

4.2 B-树

是一种多路搜索树(并不是二叉的):

  1. 定义任意非叶子结点最多只有M个儿子;且M>2
  2. 根结点的儿子数为[2,M]
  3. 除根结点以外的非叶子结点的儿子数为[M/2,M]
  4. 每个结点至少存放M/2-1(取上整)和至多M-1个关键字;(至少2个关键字
  5. 非叶子结点的关键字个数=指向儿子的指针个数-1;
  6. 非叶子结点的关键字:K[1],K[2],...,K[M-1];且K[i]<K[i+1]
  7. 非叶子结点的指针:P[1],P[2],...,P[M];(其关键字为K[1],K[2],...,K[M-1]);其中P[1]指向关键字小于K[1]的子树,P[M]指向关键字大于K[M-1]的子树,其它P[i]指向关键字在(K[I-1],K[I])之间的子树,见下图例子可理解
  8. 所有叶子结点位于同一层

       如:(M=3)

 

4.3 B+树

mysql数据库索引用B+树

B+树是B-树的变体,也是一种多路搜索树;

  1. 其定义基本与B-树相同,除了:
  2. 非叶子结点的子树指针与关键字个数相同
  3. 非叶子结点的子树指针P[i],指向关键字值属于[K[I],K[i+1]的子树) (注意B-树是开区间,不包括值K[i])
  4. 所有叶子结点增加了一个链指针
  5. 所有关键字都在叶子结点出现,即非叶子结点不保存关键字

       如:(M=3)

 

4.4 B*树

是B+树的变体,在B+树的分根和非叶子结点上再增加指向兄弟的指针;

如:

4.5 位图索引

位图索引是一种针对多个字段的简单查询设计的一种特殊的索引,使用范围比较小,只适用于字段值固定并且值的种类很少的情况,比如性别,只有男和女,或者级别,状态等等;并且只有在同时对多个这样的字段查询时才能体现出位图的优势。

位图的基本思想就是对每一个条件都用0或者1来表示,比如有5条记录,性别分别是男,女,男,男,女,那么如果使用位图索引就会建立两个位图,对应男的10110和对应女的01001,这样的好处是,当同时对多个这种类型的地段进行and或or查询时,可以使用按位与&和按位或||来直接得到结果

4.6 哈希索引

又称散列索引,就是通过散列(哈希)函数来定位的一种索引,不过很少有单独使用散列索引的,反而是散列文件组织用的比较多。散列文件组织就是根据一个键通过散列计算把对应的记录都放到同一个槽中,这样的话相同的键值对应的记录就一定是放在同一个文件里了,也就减少了文件读取的次数,提高了效率。散列索引就是根据对应键值得散列码来找到最终的索引项的技术。


5.B+树和B树的区别

B+树的非叶子结点只包含导航信息,不包含实际的值,所有的叶子结点和相连的节点使用链表相连,便于区间查找和遍历。
B+ 树的优点在于:

  • IO次数更少:由于B+树在内部节点上不包含数据信息,因此在内存页中能够存放更多的key。 数据存放的更加紧密,具有更好的空间局部性。因此访问叶子节点上关联的数据也具有更好的缓存命中率。
  • 遍历更加方便:B+树的叶子结点都是相链的,因此对整棵树的遍历只需要一次线性遍历叶子结点即可。而且由于数据顺序排列并且相连,所以便于区间查找和搜索。而B树则需要进行每一层的递归遍历。相邻的元素可能在内存中不相邻,所以缓存命中性没有B+树好。

但是B树也有优点,其优点在于,由于B树的每一个节点都包含key和value,因此经常访问的元素可能离根节点更近,因此访问也更迅速。下面是B 树和B+树的区别图:

 

6.为什么MySQL选择B+树做索引

1、 B+树的磁盘读写代价更低:B+树的内部节点并没有指向关键字具体信息的指针,因此其内部节点相对B树更小,如果把所有同一内部节点的关键字存放在同一盘块中,那么盘块所能容纳的关键字数量也越多,一次性读入内存的需要查找的关键字也就越多,相对IO读写次数就降低了。

2、B+树的查询效率更加稳定:由于非终结点并不是最终指向文件内容的结点,而只是叶子结点中关键字的索引。所以任何关键字的查找必须走一条从根结点到叶子结点的路。所有关键字查询的路径长度相同,导致每一个数据的查询效率相当。

3、B+树更便于遍历:由于B+树的数据都存储在叶子结点中,分支结点均为索引,方便扫库,只需要扫一遍叶子结点即可,但是B树因为其分支结点同样存储着数据,我们要找到具体的数据,需要进行一次中序遍历按序来扫,所以B+树更加适合在区间查询的情况,所以通常B+树用于数据库索引。

4、B+树更适合基于范围的查询:B树在提高了IO性能的同时并没有解决元素遍历的我效率低下的问题,正是为了解决这个问题,B+树应用而生。B+树只需要去遍历叶子节点就可以实现整棵树的遍历。而且在数据库中基于范围的查询是非常频繁的,而B树不支持这样的操作或者说效率太低。


 

参考资料:

https://blog.csdn.net/wl044090432/article/details/53423333

https://www.cnblogs.com/barrywxx/p/4351901.html

https://www.jianshu.com/p/7ce804f97967

https://www.cnblogs.com/tiancai/p/9024351.html

https://blog.51cto.com/13580976/2103750

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值