最通俗易懂的数据库索引结构讲解


一般一个数据库系统包含以下:

  • 存储(文件系统):将设备持久化到存储设备当中

  • 程序实例:对存储进行逻辑上的管理

    • 物理存储关系的存储管理模块
    • 优化执行效率的缓存模块
    • 对sql语句进行解析的SQL解析模块
    • 记录操作的日志管理模块
    • 进行多用户管理的权限划分模块
    • 灾难恢复模块容灾机制
    • 优化查询效率的索引模块
    • 支持并发操作的锁模块

一、为什么要使用索引

首先我们要明白,数据库的数据是存储在磁盘中的,每次读磁盘都是非常昂贵的的IO开销,而且速度非常慢,所以现在的系统都有局部读取的功能,能够将我们所要的数据的周围的数据一并读取,但是这些还不能够满足我们,仍然会出现一次查询需要多次IO,毕竟在没有索引的情况下,我们每次查询数据库基本都是全表查询,数据量少还好说,数据量稍微大些,不仅影响性能还浪费时间。所以索引就出现了。

二、索引有哪些类型呢(以mysql为例)

  • 普通索引:最基本的索引,它没有任何限制,用于加速查询。INDEX
  • 唯一索引:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。UNIQUE INDEX
  • 主键索引:是一种特殊的唯一索引,一个表只能有一个主键,不允许有空值。一般是在建表的时候 同时创建主键索引。PRIMARY KEY
  • 组合索引:指多个字段上创建的索引,只有在查询条件中使用了创建索引时的第一个字段,索引才会被使用。使用组合索引时遵循最左匹配原则(后边讲解)。INDEX name(“colum_name”,“colum_name”…)
  • 全文索引:主要用来查找文本中的关键字,而不是直接与索引中的值相比较。FULLTEXT INDEX name("")

三、索引的数据结构

1、二叉查找树进行二分查找

结构图:
在这里插入图片描述
可以看出,二叉查找树的左子节点的值是小于他的父节点的,例如上图中2小于5,右子节点均大于父节点的值。

到这里我们应该能够明白,二叉查找树结构的索引查找方法了,比如我们查找6,6>5,所以找5的右节点,6<7找7的子节点,以此类推,便可定位到,可以看出,他是对半搜索,所以时间复杂度为O(logn)。

缺点

  • 节点删除添加,会破坏其结构,可能会变成线性结构,那么其复杂度可能会变为O(n),大大降低了效率
  • 就算我们花费手段将其结构还原,我们可以看到,每个节点只能有两个节点,也就是说,一次查询可能需要较多的深度查找,这种做法增加了IO负担,浪费资源,也耗时。是不满足我们的优化查询需求。

所以为了提高效率,我们尽量降低深度,增大每个节点的子节点。由此,我们引出B-Tree

2、B-Tree结构

也称作平衡多路查找树在这里插入图片描述
实际中,每个索引子节点上限是大于3的,每个存储块(节点)包括关键字(蓝色)和指向孩子的指针(黄色),能够有多少个孩子,取决于存储块的容量和数据库的相关配置

定义:

  • 根节点至少包括两个孩子
  • 树中每个节点最多含有m个孩子(m>=2)
  • 除了根节点和叶节点外,其他每个节点至少有m/2个孩子
  • 所有叶子节点都位于同一层(叶子节点的高度都是一样的)

其余特点:

  • 关键字个数永远比指针少一个
  • 左子节点关键字的值都会比该节点的父节点关键字值小,右子节点均大于父节点关键字值,其余子节点关键字值位于父节点关键字值开区间之内,例如图上的9和10位于(8,12)

查询B数结构的索引时,也是比较简单明了的,比如我们查15,小于根节点的所有值,故查询左边,发现大于8和12,于是查询右边,15>13,继续右边,然后定位了。

优点:

  • 高度比二叉树矮得多
  • 添加或删除时,因为有其定义在,B数可以进行上移下移来保证结构完整性,避免发展成线性结构
  • 时间复杂度:O(logb(n)),b为分叉数

3、B+Tree(主流)

B+数是B数的变体,基本定义和B数相同

在一个磁盘块中,关键字数目跟指针数目是一样的
在这里插入图片描述
其特性跟B数也有点小区别

  • 父节点关键字最小值<=左子节点值<父节点中间节点值
  • 父节点关键字最大值<=右子节点值
  • 父节点关键字其余值<=其余子节点值<父节点最大值
  • 非叶子节点只存储关键字,数据只能存储在叶子节点中,也就是说哪怕在非叶子节点查询到了,也必须进入他的叶子节点
  • 所有叶子节点均由一个链指针指向下一个叶子节点,顺序由小向大连接,方便我们进行统计。比如我们查找到关键字为10的叶子节点,我们需要统计>=10的数据,直接统计后边连接的就行,就无须回到非叶子节点层进行搜索

B+树的优点:

  • 除了叶子节点,其余节点只存储关键字,这样一个磁盘块所能容纳的关键字就越多,一次能够查找的关键字就越多。也就是提高了磁盘IO性能
  • B+树查询效率更加稳定,都是需要查询到叶子节点
  • B+树更有利于对数据库的扫描,叶子节点顺序相连,更有利于数据库范围查询,效率更高

4、 Hash

在这里插入图片描述

hash索引效率非常高,一次计算就可以找到目标,时间复杂度O(1)

缺点:

  • 仅仅满足“=”,“IN”,不能使用范围查询
  • 不能利用部分索引键查询,无法用组合索引
  • 不能避免表扫描
  • 遇到大量Hash值相等的情况后性能低下

它的局限性还是很大的

索引是建得越多越好吗

答案肯定是否。

  • 数据量小的表不需要建立索引,建立会增加额外的索引开销

  • 数据变更需要维护索引,因此更多的索引意味着更多的维护成本

  • 索引是存储在磁盘上的,更多的索引页意味着需要更多的磁盘空间

    注意:

    1、索引需要占用磁盘空间,因此在创建索引时要考虑到磁盘空间是否足够

    2、创建索引时需要对表加锁,因此实际操作中需要在业务空闲期间进行

原创文章 50 获赞 101 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_42173451/article/details/105651123