2025年mysql主键和索引(mysql主键索引的数据结构)

mysql主键和索引(mysql主键索引的数据结构)索引是 mysql 非常重要的一部分 你也可能经常会看到一些关于 mysql 军规 mysql 查询优化的文章 其实这些操作的背后都是基于一定的原理的 你要想明白这些原理 首先就得知道 mysql 底层的一些东西 在这里举几个例子吧 我们都知道表的主键一般都要使用自增 id 不建议使用业务 id 是因为使用自增 id 可以避免页分裂 这个其实可以相当于一个结论 你都可以直接记住这个结论就可以了 但是如果你要弄明白什么是页分裂 或者什么情况下会页分裂 这个时候你就需要对 mysql



索引是 mysql 非常重要的一部分。你也可能经常会看到一些关于 mysql 军规、mysql 查询优化的文章,其实这些操作的背后都是基于一定的原理的,你要想明白这些原理,首先就得知道 mysql 底层的一些东西。

在这里举几个例子吧。

我们都知道表的主键一般都要使用自增 id,不建议使用业务 id ,是因为使用自增 id 可以避免页分裂。这个其实可以相当于一个结论,你都可以直接记住这个结论就可以了。

但是如果你要弄明白什么是页分裂,或者什么情况下会页分裂,这个时候你就需要对 mysql 的底层数据结构要有一定的理解了。

我这里也稍微解释一下页分裂,mysql (注意本文讲的 mysql 默认为InnoDB 引擎)底层数据结构是 B+ 树,所谓的索引其实就是一颗 B+ 树,一个表有多少个索引就会有多少颗 B+ 树,mysql 中的数据都是按顺序保存在 B+ 树上的(所以说索引本身是有序的)。

然后 mysql 在底层又是以数据页为单位来存储数据的,一个数据页大小默认为 16k,当然你也可以自定义大小,也就是说如果一个数据页存满了,mysql 就会去申请一个新的数据页来存储数据。

如果主键为自增 id 的话,mysql 在写满一个数据页的时候,直接申请另一个新数据页接着写就可以了。

如果主键是非自增 id,为了确保索引有序,mysql 就需要将每次插入的数据都放到合适的位置上。

当往一个快满或已满的数据页中插入数据时,新插入的数据会将数据页写满,mysql 就需要申请新的数据页,并且把上个数据页中的部分数据挪到新的数据页上。

这就造成了页分裂,这个大量移动数据的过程是会严重影响插入效率的。

其实对主键 id 还有一个小小的要求,在满足业务需求的情况下,尽量使用占空间更小的主键 id,因为普通索引的叶子节点上保存的是主键 id 的值,如果主键 id 占空间较大的话,那将会成倍增加 mysql 空间占用大小

我之前甚至想过为啥要用数据库来保存数据,用普通的 txt 或者 word 这类文件不行么,这个问题其实可以从几个方面来看,一个是并发访问数据加锁,另一个是数据安全性,再一个是数据的查询性能问题。
这三个方面在 mysql 中都有对应的解决方案,比如事务、锁、日志系统(binlog、redolog 等)、索引。

为了实现高效查询,就得找到一种合适的数据结构来保存数据。首先我们可以想到使用哈希表,哈希表能通过键值快速找到对应的值,但是因为哈希是无序的,一般更适用于等值查询,

但实际业务中通过会有大量的区间查询,比如查询 id 在 1-100 间的值,使用哈希的话效率就会大打折扣了。

那么就要找到一种既能满足等值查询,又能满足区间查询的数据结构了,又会很容易想到数组。数组可以通过下标快速找到对应的值,因为数组下标是有序的,所以通过遍历下标就能很高效的完成区间查询。

但是数组也有一个严重的问题,就是在删除或者插入数据的时候可能会移动大量其他数据,这是一个很大的性能消耗,所以数组一般更适合保存静态数据,比如一些历史数据,确定不会再更新的数据。

再一个就是二叉搜索树了,二叉搜索树的查找效率比较高,而且二叉搜索树的中序遍历就是一个有序数组,但依然不能很好的支持区间查询。

所以可以对二叉搜索树进行改造,树的节点不再保存具体数据,而是保存索引值,数据保存在最底层的叶子节点上,同时叶子节点间使用双链表连接起来,这样只需要先找到区间起始值的位置,然后往后遍历到终止值,即可完成区间查询。

事实上 mysql 底层采用的 B+ 树也就是这么一步步演变过来的,关于 B+ 树的详细介绍可以参考我前面的文章。

另外说一点,mysql 中有一个非常重要的模块,就是优化器,优化器的主要任务就是寻找一种更低代价方式去执行方式,通常会以扫描行数、是否需要排序、是否需要回表、是否需要临时表等来作为代价依据。

所以通常同一条 sql 在不同数据量的情况下执行情况可能会不一样,或者明明为某些 where 字段建立了索引,查询的时候偏偏又不走索引,这些情况其实都是经过优化器分析后作出的选择。因此你要知道,一条 sql 最终该怎么执行,还得看是在什么样的场景。
编程小号
上一篇 2025-02-21 12:57
下一篇 2025-02-27 20:01

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/bian-cheng-ri-ji/29375.html