概述
在讲 B+ 树的时候,说到 MySQL 底层依赖 B+ 树作为构建索引的数据结构。
在实际开发中,即便是再复杂的业务,也逃不出增删改查这四种操作,可以抽象的理解为是对数据的存储和计算,当面对海量数据时,性能就成了最重要的指标之一,而索引是提高性能的关键手段。
那么何为索引(index)呢?其实很简单,我们平时看的书或者词典通常都有目录,这个目录就是一个典型的索引,通过目录,可以快速定位到我们想要的内容的位置。
如何设计索引
知道了索引的重要性及其能力后,需要考虑一下如何将它应用到实际场景中去,在这个过程中需要考虑哪些问题或者需要解决什么难题?
- 是否是格式化数据
格式化数据是指存储于 MySQL 数据库中比较规矩的数据,可以直接拿字段构建索引。
非格式化数据是指网页这样不规矩的数据,解决的方案是提取关键字来建立索引。 - 数据状态
静态数据:只需要考虑查询效率来构建索引,因为没有插入和删除操作。
动态数据:大部分情况都是动态数据,动态数据构建索引比较复杂,不仅要考虑查询效率还要支持动态数据变化。 - 索引存储位置
存储于内存中的索引,查询速度高,但是对空间占用要求比较高。
当索引占用空间很大时可以将其存储于硬盘中,但是缺点就是查询速度没有在内存中国快。
第三种情况是索引的部分存储于内存中,部分存储于硬盘中,这样可以兼顾效率和空间。 - 查找方式
单值查找、区间查找(B+ 树)、单关键字查找、多关键字查找(搜索引擎查找网页时) - 索引不能占用太多的空间,即便是存储于硬盘中
- 还要考虑索引的维护成本
构建索引的数据结构
回顾基础的数据结构,可以大致给它们分个类:
- 支持动态集合的数据结构:散列表、红黑树、跳表、B+树
- 辅助索引:位图、布隆过滤器
- 静态数据索引:有序数组
- 散列表
增删改查操作性能很好,时间复杂度是O(1),在一些键值对数据库中应用比较广泛,一般都存储于内存中,如:Redis,Memcache。 - 红黑树
常用的平衡二叉树,增删改查效率高,时间复杂度为O(log n)。Ext 文件系统中使用红黑树实现对磁盘的索引。 - B+ 树
是一棵多叉树,构建相同数量索引,树的高度比红黑树低,更适合用于构建存储在磁盘中的索引,因为读取索引时需要的 IO 操作更少。大部分关系型数据库的索引都是使用 B+ 树实现。如:MySQL 等。 - 跳表
支持快速增删改查,并且可以通过调整索引节点个数与数据量的比例来平衡内存消耗和查询效率。Redis 中的有序集合就是用跳表构建的。 - 位图与布隆过滤器
布隆过滤器对于查询结果有一定的容错性,不能直接用于精确查找,但是可以通过它来给其他索引结构提高查询效率,在布隆过滤器中查询若是不存在,那么一定就不存在,就没必要读取索引了。 - 有序数组
通过对静态数据排序存储于有序数组中,利用二分查找高效的查询数据。