作者介绍:简历上没有一个精通的运维工程师,下面的思维导图也是预计更新的内容和当前进度(不定时更新)。
数据库是一个系统(应用)最重要的资产之一,所以我们的数据库将从以下几个数据库来进行介绍。
MySQL(本章节)
PostgreSQL
MongoDB
Redis
Etcd
一、索引是什么?
想象一下一本书的 目录。如果没有目录,你要找到某一章节,只能从第一页开始一页一页地翻(全表扫描)。而有了目录,你可以通过章节名(键)快速定位到对应的页码(磁盘地址)。
在 MySQL 中,索引(Index) 就是帮助存储引擎快速获取数据的一种数据结构。它就像数据的“目录”,通过预先排序和构建特定结构,极大减少了数据库需要扫描的数据量,从而提高了查询速度。
二、为什么需要索引?(优点与缺点)
优点:
- 大幅提高查询速度:这是最主要的目的。特别是对于大数据表的等值查询(
=
)和范围查询(BETWEEN
, >
, <
等)。 - 确保数据唯一性:唯一索引可以保证某一列或某几列的组合在表中的唯一性。
- 加速表连接:在进行多表连接(JOIN)时,如果连接条件上有索引,会极大地提高连接效率。
- 减少排序和分组的时间:
ORDER BY
(排序) 和 GROUP BY
(分组和汇总) 子句如果可以利用索引,可以避免额外的排序操作。
缺点:
- 占用额外磁盘空间:索引也是一张表,保存了主键和索引字段并指向实体表的记录,需要占用磁盘空间。
- 降低写操作性能:当对表中的数据进行增(INSERT)、删(DELETE)、改(UPDATE)时,数据库不仅需要操作数据,还需要更新对应的索引结构。索引越多,写操作的成本越高。
核心权衡:以空间换时间,并且读写性能的权衡。索引不是越多越好,需要根据实际查询需求来创建。
三、索引的数据结构
MySQL 支持多种索引数据结构,最常见的两种是:
1. B+Tree 索引 (默认)
这是 MySQL 的 InnoDB 和 MyISAM 存储引擎默认且最常用的索引类型。
- 结构:它是一种多路平衡查找树。与 B-Tree 的区别在于:
- 非叶子节点只存储键值(索引列的值)和子节点的指针,不存储数据。
- 所有数据都存储在叶子节点上,并且叶子节点之间通过指针相连,形成一个双向链表。
- 优点:
- 非常适合范围查询:由于叶子节点是链表结构,只需找到范围的起始点,然后沿着链表遍历即可,非常高效。
- 查询性能稳定:每次查询都需要从根节点遍历到叶子节点,路径长度相同,性能稳定。
- 磁盘 I/O 次数少:树的高度很低(通常只有3-4层),意味着查询任何一条记录最多只需要3-4次磁盘I/O。
99% 的场景下,你使用的都是 B+Tree 索引。
2. Hash 索引
- 原理:通过对索引列计算一个哈希码,将哈希码与对应的行数据指针存储在哈希表中。查询时,先计算查询条件的哈希值,然后在哈希表中找到对应的数据地址。
- 优点:
- 等值查询极快(
=
, IN
),时间复杂度接近 O(1)。
- 缺点:
- 使用场景:Memory 存储引擎默认使用 Hash 索引。InnoDB 支持自适应哈希索引(Adaptive Hash Index),但它是数据库内部自动管理的,用户无法手动创建。
四、索引的类型(逻辑分类)
从逻辑功能的角度,索引可以分为:
- 普通索引 (INDEX):最基本的索引,没有任何限制,仅用于加速查询。
- 唯一索引 (UNIQUE INDEX):与普通索引类似,但要求索引列的值必须是唯一的,允许有空值。
- 主键索引 (PRIMARY KEY):一种特殊的唯一索引,不允许有空值。一张表只能有一个主键索引。InnoDB 的表数据文件本身就是按主键索引组织的一棵 B+Tree(聚簇索引)。
- 复合索引(联合索引):一个索引包含多个列。例如
INDEX idx_name_age (name, age)
。这是非常重要且常用的技巧。 - 全文索引 (FULLTEXT):如上所述,用于全文搜索。
- 空间索引 (SPATIAL):用于空间数据类型。