当前位置: 首页 > web >正文

mysql底层数据结构

mysql索引是为了快速查找数据而把数据按照一定规则排列的数据结构

查看数据结构地址:Data Structure Visualization

查看mysql文件页大小(16K)

SHOW GLOBAL STATUS like 'Innodb_page_size';

数据在磁盘上随机分布,不使用索引查找需要经过多次磁盘IO,索引的作用就是为了减少磁盘IO次数

一、索引数据结构分类

1、二叉树

二叉树的规律是从根节点比左边元素大,比右边元素小;如果自增id索引字段,这时候构建的二叉树就和链表一样,如此树的高度会影响查询速度

2、红黑树

是一种平衡二叉树,会根据插入的数据做平衡,但是实际生产过程中,随着数据量增加,树的高度越高,查询的速度就会越慢

3、b树

多路平衡搜索树,每个节点横向扩展,每个节点可存储多个元素称为一页数据,减少树的高度(每个节点的元素实际存储索引值和数据)

4、b+树

和b树一样,从左到右都是有顺序的,与b树相比,b+树的叶子节点之间有指针指向,非叶子为冗余索引,非叶子节点的元素实际不存储索引值和数据,叶子节点实际索引值和存储

5、hash

经过一次hash运算就可以定位到数据所存储的地址,如果是范围查找,hash索引就会失效

二、myisam和innodb索引

现有两张表my_user1、my_user2,my_user1存储引擎为MyISAM,my_user2存储引擎为InnoDB

不同存储引擎data存储的文件如下,my_user1.frm为表结构文件,my_user1.MYD为表数据文件,my_user1.MYI为表索引文件(myisam存储引擎);my_user2.frm为表结构文件,my_user2.ibd为表索引和数据文件(innodb存储引擎);由此可见,InnoDB存储引擎将索引和数据存储在同一文件中,而MyISAM存储引擎则将索引和数据分开存放:索引存储在MYI文件中,数据存储在MYD文件中。MyISAM通过MYI文件中的索引地址定位MYD文件中的具体数据,需要额外的查找操作

三、索引分类

1、聚集索引

聚簇索引、主键索引都是聚集索引,一个表只能有一个聚集索引;主键索引所有叶子节点存储整张表的数据

2、非聚集索引

稀疏索引、二级索引是一种非聚集索引;非聚集索引叶子节点存储聚集索引值,当有数据在内存中匹配到主键索引值,再到主键索引树上查找对应的数据,这个过程叫回表

联合主键索引和非联合主键索引可以参考上面的聚集索引和非聚集索引,区别是联合索引的索引值是通过多个字段组成一个元素放到一个数据页中,且需要遵循最左前缀原则

四、其它

1、最左前缀原则

假设有一个表table,有一个联合索引,联合索引字段包含a,b,c

select * from table where a = '1' and b = '2' and c = '3'
select * from table where b = '2' and c = '3'
select * from table where c = '3'

第一条sql语句联合索引生效,因为跳过前面的字段,其它后面都是无序 

2、为什么mysql选择b+树而不选择b树

  1. b树每次查询加载根节点的容量是有限制的,而b树的非叶子节点数据页存放所有数据,也就是说b树存放元素比b+树存储的元素要少,树的高度也就越高,IO次数越多,查询越慢

  2. 如果是范围查询,b+树的叶子节点之间有指针指向下一个叶子节点,而b树没有,b+树查询到结果可以返回,而b树把根节点加载到内存,一直循环往下找到结果,由于没有指针指向,又要重新从根节点开始加载

3、为什么建议InnoDB表必须建主键,并且推荐使用整型的自增主键

  1. 如果不建主键,mysql在构建索引树时会从一列中选取不重复数据的列构建b+树,如果没有不重复数据的列,mysql会自己新建一个隐藏列,类似rowid,有点耗费性能

  2. 如果不用整型,像uuid,内部肯定是用ascii码做排序,另一个就是存储空间比整型要大

  3. 为什么要自增,假如b+树节点最大元素容量是3,当超过3个就分裂形成子元素,这时候有一个节点是3,4,9,插入一个5,如果是自增的话只要新增一个节点存储就行,现在插入导致节点分裂,树还要做一下平衡,效率比较低

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

  1. 节省空间,如果还存储其它数据,数据量大的话索引占用空间大

  2. 维护索引树方便,因为如果不管什么索引树的叶子节点都存储整张表数据,那肯定要先保证所有索引树的叶子节点都插成功才行;所以像我们这种只维护主键索引树的叶子节点就行,等主键索引插成功再把id维护到非主键索引树的叶子节点上

http://www.xdnf.cn/news/8434.html

相关文章:

  • 怎么判断一个Android APP使用了React Native 这个跨端框架
  • 【Golang】部分语法格式和规则
  • matlab时间反转镜算法
  • 2025年电工杯A题第一版本Q1-Q4详细思路求解+代码运行
  • day24Node-node的Web框架Express
  • C# Windows Forms应用程序-001
  • 国产矢量网络分析仪怎么样?能用在哪里?
  • 打破传统范式,线上 3D 画展彰显多元亮点
  • C语言---动态内存管理、柔性数组
  • unity控制相机围绕物体旋转移动
  • Maven打包SpringBoot项目,因包含SpringBootTest单元测试和Java预览版特性导致打包失败
  • 【leetcode】3356. 零数组变换②
  • 【uniapp】 iosApp开发xcode原生配置项(iOS平台Capabilities配置)
  • SFP与Unsloth:大模型微调技术全解析
  • 如何使用patch-package给npm包打补丁
  • 基于Java的话剧购票小程序【附源码】
  • 【Linux cmd】查找进程信息
  • Appium+python自动化(四)- 如何查看程序所占端口号和IP
  • Jmeter(三) - 测试计划(Test Plan)的元件
  • PostgreSQL 用户权限与安全管理
  • 量子传感器:开启微观世界的精准探测
  • Jetson系统烧录与环境配置全流程详解(含驱动、GCC、.Net设置)
  • 从JDK 8到JDK 17的主要变化
  • 《Medical SAM适配器:将分割一切模型适配于医学图像分割》|文献速递-深度学习医疗AI最新文献
  • Git企业级——进阶
  • NHANES指标推荐:MHR
  • leetcode:2469. 温度转换(python3解法,数学相关算法题)
  • docker swarm 启动容器报错日志查看方式
  • OpenHarmony 5.0中状态栏添加以太网状态栏图标以及功能实现
  • HTA8127内置升压的77W单体声D类音频功放