深入解析MySQL索引数据结构

作者:老郑 时间:2024-01-19 23:40:25 

目录
  • 概述

  • 索引数据结构

    • 二叉树

    • 红黑树

    • B-Tree

    • B+Tree

    • Hash

  • 索引

    • InnoDB 索引实现(聚集)

    • 索引文件和数据文件是分离的(非聚集)

    • 聚集索引和非聚集索引

    • 联合/复合索引

  • 参考资料

    • 总结

      概述

      索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息。

      索引数据结构

      二叉树

      二叉树(binary tree)是指树中节点的度不大于 2 的有序树,它是一种最简单且最重要的树。二叉树的递归定义为:二叉树是一棵空树,或者是一棵由一个根节点和两棵互不相交的,分别称作根的左子树和右子树组成的非空树;左子树和右子树又同样都是二叉树

      对于数组 {1,2,3,4,5} 数据结构将成为了链表

      特点:

      • 父节点下面有两个子节点。

      • 右边节点的数据大于左边节点的数据。

      深入解析MySQL索引数据结构
      二叉树.png

      红黑树

      红黑树是一种特定类型的二叉树,它是在计算机科学中用来组织数据比如数字的块的一种结构。若一棵二叉查找树是红黑树,则它的任一子树必为红黑树。

      红黑树是一种平衡二叉查找树的变体,它的左右子树高差有可能大于 1,所以红黑树不是严格意义上的平衡二叉树(AVL),但对之进行平衡的代价较低, 其平均统计性能要强于 AVL 。

      由于每一棵红黑树都是一棵二叉排序树,因此,在对红黑树进行查找时,可以采用运用于普通二叉排序树上的查找算法,在查找过程中不需要颜色信息。

      红黑树数据结构如下图:

      深入解析MySQL索引数据结构
      红黑树数据结构.png

      特点:

      • 红黑树是每个结点都带有颜色属性的二叉查找树,颜色或红色或黑色。

      • 结点是红色或黑色。

      • 根结点是黑色。

      • 所有叶子都是黑色。(叶子是NIL结点)

      • 每个红色结点的两个子结点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色结点)

      • 从任一节结点其每个叶子的所有路径都包含相同数目的黑色结点。

      • 这些约束强制了红黑树的关键性质: 从根到叶子的最长的可能路径不多于最短的可能路径的两倍长。结果是这个树大致上是平衡的。因为操作比如插入、删除和查找某个值的最坏情况时间都要求与树的高度成比例,这个在高度上的理论上限允许红黑树在最坏情况下都是高效的,而不同于普通的二叉查找树。

      • 是性质4导致路径上不能有两个连续的红色结点确保了这个结果。最短的可能路径都是黑色结点,最长的可能路径有交替的红色和黑色结点。因为根据性质5所有最长的路径都有相同数目的黑色结点,这就表明了没有路径能多于任何其他路径的两倍长。

      • 因为红黑树是一种特化的二叉查找树,所以红黑树上的只读操作与普通二叉查找树相同。

      B-Tree

      • 叶子结点具有相同的深度,叶节点的指针为空

      • 所有元素不重复

      • 节点中的数据索引从左到右边递增排列

      深入解析MySQL索引数据结构B树数据结构.png

      B+Tree

      • 非叶子结点不存储数据,只存储索引(冗余),可以存放更多的索引

      • 叶子结点包含所有索引字段

      • 叶子结点用指针链接,提高区间访问的性能(可以提升范围查找的效率)

      深入解析MySQL索引数据结构B+树数据结构.png

      特点关键字:节点内有序,叶子结点指针链接,非叶子结点存储索引(冗余)

      查询mysql 索引的数据页的大小:


      mysql> show global status like 'Innodb_page_size';
      +------------------+-------+
      | Variable_name    | Value |
      +------------------+-------+
      | Innodb_page_size | 16384 |
      +------------------+-------+

      为什么设置 16kb 呢?

      Hash

      • 对索引的 key 进行一次 hash 计算就可以定位出数据存储的位置

      • 很多的时候 hash 索引要比 B+ 树索引更高效

      • 仅能满足 “=” , “in”  不支持范围查询

      • 存在 hash 冲突问题

      深入解析MySQL索引数据结构
      Hash 数据结构.png

      索引

      InnoDB 索引实现(聚集)

      表数据文件本身就是按 B+Tree 组织的一个索引结构文件

      聚集索引-叶子节点包含了完整的数据记录

      为什么 InnoDb 表必须有主键,并且推荐使用整型的自增主键?

      • 如果没有设置索引的话,MySQL 会选择一个数据唯一的列作为主键索引, 如果找不这样的列。会去做创建一个隐藏列类似  rowid。

      • 表数据文件按照 B+Tree 的数据结构维护,在叶子节点维护的是该行的数据。所以必须有主键。

      • 整型更方便 B+Tree 排序,自增的话,对于数据结构的存放更快,  顺序存放,不需要进行大量树的平衡操作。

      为什么非主键索引结构叶子节点的存储的是主键值?

      • 一致性, 让主键索引先成功,然后再去更新非主键索引关系

      • 节省存储空间。

      主键索引示意图:

      深入解析MySQL索引数据结构
      InnoDB 索引实现.png

      非主键索引示意图图片

      深入解析MySQL索引数据结构

      如果查询的是通过 name = Alice 去查询的时候:

      1. 走非主键索引去查询,查询完后拿到信息(Alice, 18)。其实这里也是一个非聚簇索引

      2. 然后进行回表查询,再次通过主键去查询做回表查询。

      两个数据文件:

      .frm 主要是存储表结构信息

      .ibd 主要是存储索引和数据

      MyISAM 索引文件(非聚集)

      索引文件和数据文件是分离的(非聚集)

      深入解析MySQL索引数据结构
      MyISAM 存储引擎索引.png

      三个数据文件:

      .frm 数据结构文件

      .myd 文件主要是存储数据

      .myi 文件主要是存储索引信息

      聚集索引和非聚集索引

      特征:

      聚集/非聚集主要是索引文件是否和数据文件在一起。

      查询效率上来说聚集索引不会跨文件查询效率会更加快。

      联合/复合索引

      多个字段组织成一个共同的索引

      深入解析MySQL索引数据结构
      组合索引.png

      最左前缀原理为什么这样来使用?

      索引的数据是被排序的,如果跳过字段的话是无法被使用的。

      示例:


      where name = 'Jeff' and age = 22              -- 命中索引

      where age = 30  and postatin='manager'  -- 不命中索引

      where postation = 'dev'                            -- 不命中索引

      参考资料

      百度百科

      来源:https://mp.weixin.qq.com/s/OERaNP7PoolWkDvEVNCFOQ

      标签:mysql,索引,数据结构
      0
      投稿

      猜你喜欢

    • mysql全文搜索 sql命令的写法

      2024-01-25 04:45:38
    • mysql 5.7.18 winx64 免安装 配置方法

      2024-01-27 14:00:08
    • Python enumerate遍历数组示例应用

      2023-06-10 16:59:26
    • Go REFLECT Library反射类型详解

      2024-04-26 17:25:15
    • Python序列化与反序列化pickle用法实例

      2022-04-14 11:44:06
    • flask使用session保存登录状态及拦截未登录请求代码

      2021-02-22 12:00:57
    • 对python调用RPC接口的实例详解

      2022-12-30 00:09:20
    • python利用7z批量解压rar的实现

      2021-05-02 18:58:31
    • 服务端XMLHTTP(ServerXMLHTTP in ASP)基本应用(上)

      2008-11-11 12:49:00
    • python进行TCP端口扫描的实现

      2021-04-18 12:33:32
    • 部署ASP.NET Core程序到Windows系统

      2024-05-09 09:04:38
    • DB为何大量出现select @@session.tx_read_only 详解

      2024-01-15 15:26:15
    • python3 读写文件换行符的方法

      2021-09-29 11:21:22
    • Python中如何导入类示例详解

      2023-05-09 08:35:58
    • Vue iframe更改src后页面未刷新问题解决方法

      2024-05-09 15:14:15
    • Pandas读存JSON数据操作示例详解

      2022-05-24 08:14:03
    • IE7的web标准之道 Ⅰ

      2008-08-13 12:42:00
    • 在pycharm中文件取消用 pytest模式打开的操作

      2022-06-20 18:16:19
    • python计算一个序列的平均值的方法

      2023-08-25 06:40:17
    • 支持PyTorch的einops张量操作神器用法示例详解

      2023-10-17 23:13:06
    • asp之家 网络编程 m.aspxhome.com