深入解析MySQL索引数据结构


Posted in MySQL onOctober 16, 2021

概述

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

索引数据结构

二叉树

二叉树(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'                            -- 不命中索引

参考资料

百度百科

总结

到此这篇关于MySQL索引数据结构的文章就介绍到这了,更多相关MySQL索引数据结构内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

MySQL 相关文章推荐
MySQL InnoDB ReplicaSet(副本集)简单介绍
Apr 24 MySQL
MySQL优化之如何写出高质量sql语句
May 17 MySQL
简单了解 MySQL 中相关的锁
May 25 MySQL
MySQL 亿级数据导入导出及迁移笔记
Jun 18 MySQL
MySQL 外键约束和表关系相关总结
Jun 20 MySQL
mysql定时自动备份数据库的方法步骤
Jul 07 MySQL
MySQL 5.7常见数据类型
Jul 15 MySQL
mysql timestamp比较查询遇到的坑及解决
Nov 27 MySQL
关于k8s环境部署mysql主从的问题
Mar 13 MySQL
MySQL创建管理RANGE分区
Apr 13 MySQL
Mysql 8.x 创建用户以及授予权限的操作记录
Apr 18 MySQL
Mysql 如何合理地统计一个数据库里的所有表的数据量
Apr 18 MySQL
MySQL数据库必备之条件查询语句
Oct 15 #MySQL
MySQL实例精讲单行函数以及字符数学日期流程控制
MySQL数据库超时设置配置的方法实例
MyBatis 动态SQL全面详解
MySQL中datetime时间字段的四舍五入操作
mysql如何能有效防止删库跑路
Oct 05 #MySQL
浅谈MySQL表空间回收的正确姿势
You might like
PHP flock 文件锁详细介绍
2012/12/29 PHP
php之Memcache学习笔记
2013/06/17 PHP
PHP文件上传问题汇总(文件大小检测、大文件上传处理)
2015/12/24 PHP
PHPCMS忘记后台密码的解决办法
2016/10/30 PHP
学习YUI.Ext 第六天--关于树TreePanel(Part 1)
2007/03/10 Javascript
几个有趣的Javascript Hack
2010/07/24 Javascript
ie浏览器使用js导出网页到excel并打印
2014/03/11 Javascript
jQuery使用andSelf()来包含之前的选择集
2014/05/19 Javascript
Nodejs中读取中文文件编码问题、发送邮件和定时任务实例
2015/01/01 NodeJs
js实现鼠标滑过文字链接色彩变化的效果
2015/05/06 Javascript
分享使用AngularJS创建应用的5个框架
2015/12/05 Javascript
javascript实现在网页中运行本地程序的方法
2016/02/03 Javascript
Jquery组件easyUi实现表单验证示例
2016/08/23 Javascript
AngularJS实现星星等级评分功能
2016/09/24 Javascript
详谈js中window.location.search的用法和作用
2017/02/13 Javascript
动态Axios的配置步骤详解
2018/01/12 Javascript
js事件触发操作实例分析
2019/06/21 Javascript
three.js利用gpu选取物体并计算交点位置的方法示例
2019/11/25 Javascript
nodejs开发一个最简单的web服务器实例讲解
2020/01/02 NodeJs
[52:41]OG vs IG 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/20 DOTA
用python实现批量重命名文件的代码
2012/05/25 Python
小小聊天室Python代码实现
2016/08/17 Python
详解python实现小波变换的一个简单例子
2019/07/18 Python
利用pytorch实现对CIFAR-10数据集的分类
2020/01/14 Python
解决Tensorflow占用GPU显存问题
2020/02/03 Python
解决Pycharm中恢复被exclude的项目问题(pycharm source root)
2020/02/14 Python
python GUI库图形界面开发之PyQt5时间控件QTimer详细使用方法与实例
2020/02/26 Python
python支持多继承吗
2020/06/19 Python
Python 的 f-string 可以连接字符串与数字的原因解析
2021/02/20 Python
美国内衣品牌:Leonisa
2016/08/14 全球购物
Dr.Jart+美国官网:韩国药妆品牌
2019/01/18 全球购物
Turnbull & Asser官网:英国皇室御用的顶级定制衬衫
2019/01/31 全球购物
幼儿园老师辞职信
2014/01/20 职场文书
2014年中秋寄语
2014/08/11 职场文书
中学教师师德师风承诺书
2015/04/28 职场文书
Python如何使用logging为Flask增加logid
2021/03/30 Python