Mysql底层数据结构学习总结

2023-11-10

索引数据结构

Mysql数据表中的数据在磁盘中分布位置可能是不连续的,在读取数据时,每读取一条数据就进行一次磁盘IO效率是很低的,为了减少IO次数,索引就诞生了,通过索引,我们可以快速定位到数据位置,增加查询效率,索引是一种排好序的数据结构。
索引的几种数据结构:
二叉树:
如下图所示:二叉树会把数据分成两组,值小的数据放左边,大的放右边,同样是找89,如果用链表的方式查,需要查6次,而二叉树只需要查两次,极大的提升了效率。
在这里插入图片描述
但Mysql底层没有采用这中数据结构,比如Col1的值是顺序增长的,这种单边增长的值在二叉树中和链表没有什么区别,也是去做顺序查找,对查询效率没什么帮助。
请添加图片描述
红黑树:
又叫自平衡二叉树,它会自动优化二叉树的结构,下图中,二叉树查询需要6次,红黑树只要3次,但是数据量大的时候,它的树的高度会很高,从根节点查询到叶子结点也会经历多次IO,效率也很慢,所以也不是Mysql的数据结构。
请添加图片描述
B-Terr:
也不是Mysql的数据结构, 这种数据结构中,会在一个大的数据节点里存储很多小的索引元素,使每次IO可以把一批索引加载到内存中,提升查询效率,其中data存储的是索引所在行的磁盘文件地址(K-V结构),节点中的数据索引按照从左到右递增排列。
请添加图片描述
B+Terr:
Mysql底层使用这种数据结构,可以说是对B-Tree的优化,节点中的索引也是从左到右递增排列,data数据都存储在叶子节点,多个叶子节点组成一个磁盘页,叶子节点之间通过指针链接Mysql中把B+Tree优化成了双向指针,指针存储相邻磁盘页的地址。非叶子节点只存储引,并且节点中的每一个元素值就是它指向的下一层节点的磁盘页的第一个值。在构建B+Tree的时候,每个磁盘页的第一个元素会存储在非叶子索引中,通过二分查找法,可以快速定位数据行在磁盘中的地址。
请添加图片描述
Mysql中一个节点的大小为16kb,例如一个索引类型是bigint,占8字节,加上下一个磁盘的文件地址6字节是14字节,一个非叶子节点就可以放1170个元素。叶子节点不太一样,因为存储引擎不同,data在Innodb中存储整行数据信息,在Mylsam中存储磁盘地址信息,如果是Innodb,每行1kb也能存储16个元素。假设树的高度为三,一个B+Tree能存储的数据量就是:1170 X 1170 X 16 大概2200万,得出结论就是,同样的数据量情况下,每个节点中能存储的索引元素越多,树的高度就会越小,查询效率就越快。

Hash:
Mysql底层还有一种Hash索引数据结构,如果把一列数据作为Hash索引,在插入一行记录时,会把插入值的Hash值定位到Hash桶中,桶中的Hash碰撞,会以链表的方式存储。查找的时候也会根据查找值的Hash值去Hash桶中定位,然后遍历链表,取出对应的索引元素,以及索引所在行的磁盘文件地址。
虽然这种数据结构查询快,但是没有数据大小的概念,所以这种数据结构仅能满足 “=”,“IN”,范围查询会导致全表扫描,所以也应用较少。
由于Mysql的B+Tree叶子节点有双向指针,并且是顺序排列的,就可以很好的支持范围查找。
在这里插入图片描述
B-Tree和B+Tree的区别:
1、B-Tree的非叶子节点也存储Data,B+Tree只用叶子节点存储Data,非叶子节点只用来存储索引。同样的数据量情况下,B+Tree每个节点中能存储的索引元素就更多,树的高度就更小,查询速度更快。
2、B-Tree的叶子节点没有指针,B+Tree的叶子节点用指针连接,由于B-Tree没有指针链接,所以做范围查找的时候就会很慢,因为跨区间查找的时候,会重新从根节点向下定位,所以B+Tree区间的访问性能更好。


存储引擎

Mylsam
Mylsam索引文件和数据文件是分离的
对应三个文件:frm:存储表结构信息、MYD:存储数据行、MYI:存储索引
使用B+Tree作为索引结构,叶节点的data域存放的是数据记录的地址。
查询一条数据的时候,如果查询条件增加了索引,会先从MYI文件中找到对应行的索引信息,在通过索引中data的磁盘地址值去MYD文件查询数据。
请添加图片描述
Innodb
Innodb表数据文件本身就是按B+Tree组织的一个索引结构文件
对应两个文件:frm:存储表结构信息、ibd:存储索引及数据行
该存储引擎会把表数据直接存储到叶子节点的data里
`Innodb的主键索引就是聚集索引,Mylsam是非聚集索引

`
请添加图片描述

为什么建议Innodb表必须建主键,并且推荐使用整型的自增主键?
1、为什么建主键:Innodb表创建的时候一定会用B+Treel来组织一个索引结构,主键是自带主键索引的,所以说建了主键的话会直接用主键来组织索引结构。如果不建主键,它会从表中选择一列所有元素都不相等的列,把这个列来当成组织B+Tree的数据列,如果没有这样的列,Mysql会自动建一个隐藏列用来组织索引结构。
2、为什么用整型:如果使用不是整型的UUID做主键,在查询阶段会用AscII码去比对大小,效率就会降低,整型的主键对比大小就会快很多,并且整形占用空间也比较小,尤其数据量大时可以节约磁盘空间。
3、为什么用自增:如果使用非自增的UUID做主键,在插入新数据时,因为叶子节点是顺序排列的,如果不是有序的值,就会导致节点分裂,分裂还可能导致树做自平衡。但如果使用自增主键,每次插入都是往后增加新节点,就不会出现这些情况,效率会提高很多。
为什么非主键索引结构叶子节点存储的是主键值?
主要是为了节约存储空间,因为主键的叶子节点已经存储了数据,所以就没必要再存储数据。
非主键索引是非聚集索引,这样设计的缺点是非主键索引找到叶子节点的主键值后,会做回表操作(重新回到聚集索引中找到真正的数据行)。


索引类型

聚集索引: 索引结构和数据一起存放的索引。
非聚集索引: 索引结构和数据分开存放的索引。
比如字典中,用‘拼音’查汉字,就是聚集索引。因为正文中字都是按照拼音排序的。而用‘偏旁部首’查汉字,就是非聚集索引。
Innodb的主键索引就是聚集索引,Mylsam是非聚集索引
密集索引: 叶子节点保存的不只有索引键值,还有该行数据的其他列信息。一个表只有一个密集索引
稀疏索引: 叶子节点保存的只有索引键值,还有该行数据的地址值。
Mylsam:所有索引都是稀疏索引
Innodb:有且只有一个密集索引
Innodb稀疏索引选择规则:
1、有主键,主键是密集索引
2、没有主键,第一个唯一非空索引是密集索引
3、没有主键,没有唯一非空索引,会自动生成一个隐藏索引,把这个索引当作密集索引


联合索引数据结构

在这里插入图片描述
联合索引就是由多个字段组成的一个索引,上图示例是一个联合主键索引,联合索引也是B+Tree结构 ,会先根据第一个字段的值排序,如果值一样再根据第二个字段值排序,以此类推直到排序成功。如果是联合非主键索引,可能会出现所有值都相同的情况,这种情况就会根据叶子节点中主键索引去排序。
所以,联合索引在建立的时候就是排好序的,我们用的时候也要根据建立索引时的字段顺序来用,这就是最左前缀原则。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Mysql底层数据结构学习总结 的相关文章

随机推荐

  • PPT制作 ---------插入图片背景颜色与模板的背景颜色不一致

    今天在制作ppt时候 遇到插入图片背景颜色与模板的背景颜色不一致 这样做出来效果不好 在网上查了攻略后 可以利用ppt自带的图片删除背景来调节 一顿操作后 记下来说不定以后工作时候需要使用
  • Unity人形动画反向动力学IK动画实现

    什么是反向动力学 以手掌移动为例子 正向动力学 这个 力 是由你的身体躯干发出的 改变你的手臂位置 带动你的手掌位置移动 反向动力学 这个 力 是直接在你的手掌上 直接改变你手掌的位置 并且通过手臂进而带动整个身体 力 传递的方向是相反的所
  • Java反射使用示例

    当我们使用 Java 反射时 有时需要在运行时动态地调用某个类的方法 例如使用配置文件指定要调用的方法 或者根据用户输入来决定调用哪个方法等 下面我们就来看几个动态调用方法的例子 调用无参方法 假设有一个类名为 MyClass 它有一个无参
  • 华为OD机试真题-缓存需要最少金币数【2023.Q1】

    题目描述 静态扫描可以快速识别源代码的缺陷 静态扫描的结果以扫描报告作为输出 1 文件扫描的成本和文件大小相关 如果文件大小为N 则扫描成本为N个金币 2 扫描报告的缓存成本和文件大小无关 每缓存一个报告需要M个金币 3 扫描报告缓存后 后
  • 第三节课总结之关于this指向,变量提升以及跨域的解决方案

    this 变量提升 关于继承 跨域解决方法 gt gt this指向 Js是静态作用域 是在定义阶段就决定好了的 而不是在执行阶段才决定的 参考资料 https developer mozilla org en US docs Web Ja
  • Effective C++ 学习笔记 《六》

    Item 6 Explicitly disallow the use of compiler generated functions you do not want 其实这一节的内容是和item5紧密相连的 上一节的核心围绕着编译器会自动生
  • 一个缩进符引发的错误:NotImplementedError

    class EnDecoder nn Module def init self super EnDecoder self init 定义Encoder self Encoder nn Sequential nn Linear 784 512
  • 时钟分频的几个细节理解

    时钟分频原理简单 但需要注意几个细节 计数器分频 是基于源时钟div2 4 8 16 32 64 如果基于分频器串联 那么需要定义很多分频时钟 提升sdc时钟定义的复杂性 计数器分频 要注意所有div2 4 8 16 32 64 需要保证同
  • 申请Mob的SMSSDK的短信验证功能及获取包名和MD5签名

    当下很多App的登录方式多样化 但最常用的要数手机验证码登录了 所以如何实现这个功能便成了众多Android开发者关注的问题 所以我推荐一个网站 http www mob com 以便大家借助它的SMSSDK来完成短信验证码的功能 点击创建
  • 华为交换机 配置Console接口登陆认证

    拓扑图 1 认证方式一 密码 不安全 输入密码
  • pycharm里面离线安装dgl

    这两天安装dgl是真的头大 简直各种奇葩问题都能遇到 整整一天全在搞这些事 踩了各种坑之后 终于成功了 简直留下了感动的泪水 各种方法都没成功 最后是采用了离线安装的方法才成功的 step01 百度 dgl离线安装包 然后选择适合自己电脑的
  • Docker专题-入门与运维

    文章目录 Docker专题 基础知识 1 发展缘由 Docker 为什么要使用Docker 2 架构 3 基于Docker搭建私有镜像仓库 4 常见工具 5 常见命令 6附录 Docker专题 基础知识 1 发展缘由 1960年IBM开始推
  • 让vue项目支持glsl语法

    如果你想让Vue项目支持GLSL OpenGL着色语言 语法 你需要使用特殊的加载器使Webpack能够加载和解析GLSL文件 这一般可以通过下面的步骤实现 Install webpack glsl loader npm install w
  • GNU Radio + NI USRP B210模拟物理层(一):安装UHD与GNU Radio

    GNU Radio NI USRP B210模拟物理层 一 安装UHD与GNU Radio GNU Radio NI USRP B210模拟物理层 一 GNU Radio的环境搭建 一 环境搭建 1 硬件环境与版本选择 2 UHD安装 3
  • MAVEN-Maven项目的依赖项爆红、无法下载依赖(Dependencies)或Jar包

    首先我的这份文章只是提高一种解决思路 我不能保证它一定正确 只是作为一种思路来为大家解决maven项目报错 我在学习SSM框架的时候 我的Maven项目中我引用的依赖项频繁报错 我在网上寻找解决方案 找到的是比较普遍性的错误 而我报的错误比
  • vuecli项目打包

    1 有几个问题 1 你知道软件的开发流程吗 答 需求获取 需求分析 设计 开发 测试 打包部署 上线 2 为什么要打包 答 前端的html css js越来越多 打开一个页面发送http也就变得很多 让后端服务器有很大压力 前端不利于性能优
  • 写代码思维1

    先要有思路 然后再开始写代码 刚开始可以先将思路写在文档上 比如流程图之类 然后再将其转化为代码 思路 翻译成代码 开关灯flag按钮思维 include
  • 力导向图知识图谱可视化(节点可点击)

    用d3 js的力导向图写了一个知识图谱可视化的demo 节点可点击着实费了我不少功夫 如果小伙伴有更简单的方法还求留言呢 由于数据市实验室的某项目 不太好直接贴出来 反正这样的格式就好 反正是给大家参考的 name name type 0
  • 时间序列完全教程(R)

    简介 在商业应用中 时间是最重要的因素 能够提升成功率 然而绝大多数公司很难跟上时间的脚步 但是随着技术的发展 出现了很多有效的方法 能够让我们预测未来 不要担心 本文并不会讨论时间机器 讨论的都是很实用的东西 本文将要讨论关于预测的方法
  • Mysql底层数据结构学习总结

    索引数据结构 Mysql数据表中的数据在磁盘中分布位置可能是不连续的 在读取数据时 每读取一条数据就进行一次磁盘IO效率是很低的 为了减少IO次数 索引就诞生了 通过索引 我们可以快速定位到数据位置 增加查询效率 索引是一种排好序的数据结构