MySQL存储引擎的实现要素分析

 更新时间:2023年09月14日 14:13:01   作者:jump__jump  
这篇文章主要为大家介绍了MySQL存储引擎的实现要素分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

引言

众所周知,MySQL 的 InnoDB 存储引擎使用了 B+ 树作为索引实现,那么为什么不使用其他的数据结构呢?数组、链表或者哈希表。实现存储引擎究竟需要什么条件呢?

我们现在先以存储最简单的数据为例,这里的数据类似于 json 对象。有 key 和 value。

{
    "0": "value1",
    "1": "value2" 
}

最简单的存储引擎必须实现以下三个方法:

  • read: (key: number) => value 查找 key 并返回 value
  • write: (key: number, value) => void 查找并插入 key 以及 value
  • scan: (begin: number, end: number) => value[] 查找返回 key 范围内数据

简单数据结构

对于开发项目来说,能使用最简单的数据结构完成项目是非常棒的,这意味着更少的 bug 和更少的时间。

有序数组

如果当前有序数组的位置和存储的 key 可以一一对应的话,也就是数组 index 对应 key(没有对应也就是稀疏数组),我们的 read 和 write 方法的时间复杂度会是 O(1),scan 方法也是 O(1)。但数据量稍大就扛不住了。

退而求其次,不存在位置对应主键的情况下,有序数组紧密存储,这样可以通过二分查找,read 和 scan 方法的时间复杂度为 O(log2n)。但 write 方法成本会高到离谱。

综上所属,有序数组是在数据量少的情况下可以用来做存储引擎的。

哈希表

不考虑空间是不可能的,那么直接舍弃 scan 方法呢?在某些业务场景下是可以不使用 scan 方法的。

哈希表使用一对多的组织方式来实现 read 和 write。先对 key 进行 hash 运算然后再寻址,性能基本接近于 O(1)。

综上所属,哈希表在不考虑 scan 方法的情况下是可以用来做存储引擎的。

二叉平衡树

二叉平衡树相对 hash 和有序数据来说是一个折衷方案。该数据结构是通过链表实现的,所以不需要大块内存。它的 read 和 write 都是 O(log2n),虽然 scan 遍历慢的难以忍受,但是它能够实现这三个方法了。

综上所属,二叉平衡树是可以用来做存储引擎的,但有一定的局限性。

要素分析

在分析上面几种数据结构后,我们不难得出结论。

  • 有序性是实现 scan 方法的前提条件
  • 局部性是提升 scan/read 方法性能的必要条件

这里我们提到了局部性,那么局部性究竟是什么呢?

通常来说,良好的计算机程序需要良好的局部性,局部性主要有:

  • 时间局部性 :指的是同一个内存位置,从时间维度来看,它能够在较短时间内被多次引用
  • 空间局部性 :指的是同一个内存位置,从空间维度来看,它附近的内存位置能够被引用

仔细分析一下,scan 方法和空间局部性有关。如果使用平衡二叉树来作为查询的数据结构。scan 的性能是非常差的,但是使用有序数组来作为数据结构 scan 可以直接遍历获取两者之间的数据,性能非常高。

同时,局部性也和 read 性能有很大关系。使用二分法来查询数据。局部性较低的情况下,read 需要多次从磁盘加载数据。如果局部性高,直接一次加载数据即可。

那是不是局部性越高越好呢?不是这样的。一方面局部性高会占用较高的内存。另一方面,局部性过高会导致 write 方法变慢,因为局部性高了,write 方法需要移动的数据也就多了。

平衡二叉树是唯一能在现实世界中实现 3 个方法的数据结构,局部性是提升 scan 方法性能的必要条件。那么把两者结合呢?把平衡二叉树的结点构造成一个个有序数组,这样就可以得到两个方案的优点了。

  • 对于有序数组来说,通过拆分数组,使得在 write 方法的成本大大减少
  • 对于平衡二叉树来说,通过节点替换,大大增加了局部性,让 scan 方法性能成本大大减少

事实上,只要能够低成本且高效的维持数据有序的数据结构都可以作为存储引擎。无论是 B 树, B+ 树或者 跳表。同时每个数据结构都有其对应的侧重点。只要抓住这几个点,就不难分析出为什么当前存储引擎使用该数据结构作为索引了。

以上就是MySQL存储引擎的实现要素分析的详细内容,更多关于MySQL存储引擎的资料请关注脚本之家其它相关文章!

相关文章

  • 浅谈mysql 针对单张表的备份与还原

    浅谈mysql 针对单张表的备份与还原

    下面小编就为大家带来一篇浅谈mysql 针对单张表的备份与还原。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-03-03
  • mysql完整备份时过滤掉某些库的方法

    mysql完整备份时过滤掉某些库的方法

    下面小编就为大家带来一篇mysql完整备份时过滤掉某些库的方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-03-03
  • mysql8.0忘记密码的详细解决方法

    mysql8.0忘记密码的详细解决方法

    很早前安装了MYSQL,现在由于需要使用MYSQL但忘记密码,所以下面这篇文章主要给大家介绍了关于mysql8.0忘记密码的详细解决方法,文中通过图文介绍的非常详细,需要的朋友可以参考下
    2022-06-06
  • MySQL系列之十 MySQL事务隔离实现并发控制

    MySQL系列之十 MySQL事务隔离实现并发控制

    今天的内容就和大家聊一聊MySQL数据库中关于MySQL事务隔离实现并发控制的问题,主要是基于锁实现控制技术
    2021-07-07
  • mysql unique key在查询中的使用与相关问题

    mysql unique key在查询中的使用与相关问题

    今天小编就为大家分享一篇关于mysql unique key在查询中的使用与相关问题,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-04-04
  • 详解如何使用DockerHub官方的MySQL镜像

    详解如何使用DockerHub官方的MySQL镜像

    MySQL是一个广泛使用的开源关系型数据库,那如何获取Mysql Docker镜像?下面通过这篇文章来一起看看如何使用DockerHub官方的MySQL镜像,有需要的朋友们可以参考借鉴。
    2016-12-12
  • 深入解析mysql.sock不见的问题

    深入解析mysql.sock不见的问题

    本篇文章是对mysql.sock不见的问题进行了详细的分析介绍,需要的朋友参考下
    2013-06-06
  • mysql学习笔记之表的基本操作

    mysql学习笔记之表的基本操作

    本文给大家分享的是MySQL学习笔记系列文章的入门篇,主要讲述MySQL表的基本操作命令,非常详细,有需要的小伙伴可以来查看下
    2017-02-02
  • MySQL由浅入深掌握连接查询

    MySQL由浅入深掌握连接查询

    连接查询是关系数据库中最主要的查询,主要包括内连接、外连接和交叉连接等。通过连接运算符可以实现多个表查询。连接是关系数据库模型的主要特点,也是它区别于其它类型数据库管理系统的一个标志
    2022-03-03
  • Mysql错误1366 - Incorrect integer value解决方法

    Mysql错误1366 - Incorrect integer value解决方法

    这篇文章主要介绍了Mysql错误1366 - Incorrect integer value解决方法,本文通过修改字段默认值解决,需要的朋友可以参考下
    2014-09-09

最新评论