MySQL两种存储引擎及索引对比

MySQL两种存储引擎及索引对比

  • 前言
  • 存储引擎
    • 主要区别
    • 相关命令
    • 存储引擎1: MyISAM
    • 存储引擎2: InnoDB
    • 其他存储引擎:
  • 索引
    • 聚集(聚簇)索引
    • 二级索引
  • 常见面试题
    • 为什么 DBA 都建议表中一定要有主键,而且推荐使用整型自增?
    • 为什么要有主键?
    • 为什么推荐使用整型自增?
  • 参考资料

前言

MySQL是怎么存储数据的呢?

在之前我们聊过了**为什么 MySQL 索引要用 B+tree ,而且还这么快。**里面曾多处提到了找数据要从我们电脑的磁盘上找,今天就来说一说 MySQL 中的数据在磁盘上,它到底是如何进行存储的?长什么样?

存储引擎

百度百科是这样定义存储引擎的:MySQL 中的数据用各种不同的技术存储在文件(或者内存)中,这些不同的技术以及配套的相关功能在 MySQL 中被称作存储引擎。

简单来说就是**不同的存储引擎,我们的数据存储的格式也会不一样。**就好比图片有不同的格式,比如:.jpg, .png, .gif 等等……


扫盲:存储引擎是作用在上的。

现在 MySQL常用的存储引擎有两种:MyISAMInnoDB

MySQL 5.5之前MyISAM 是默认的存储引擎。

MySQL 5.5开始InnoDB 是默认的存储引擎。

主要区别

MyISAMInnoDB
事务不支持❌支持
表/行锁只有表锁还引入了行锁
外键不支持❌支持✔
全文索引支持✔版本5.6 开始支持
读写速度更快更慢

MyISAM 最致命的一点就是不支持事务,而 InnoDB 支持。所以现在 InnoDB 已经成为我们使用的标配、最主流的存储引擎了。

相关命令

查询当前数据库支持的存储引擎

show engines;

查询当前默认的存储引擎

show variables like '%storage_engine%';

查询表的相关信息

show table status like '表名';

存储引擎1: MyISAM

每个 MyISAM 表都以3个文件存储在磁盘上。这些文件的名称以表名开头,以扩展名指示文件类型。

.frm 文件(frame)存储表结构

.MYD 文件(MY Data)存储表数据

.MYI 文件(MY Index)存储表索引

MySQL 里的数据默认是存放在安装目录下的 data 文件夹中,也可以自己修改。

在这里插入图片描述

下面我创建了以 MyISAM 作为存储引擎的一张表 t_user_myisam。

CREATE TABLE `t_user_myisam` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',`name` varchar(50) DEFAULT NULL COMMENT '姓名',`age` int(3) DEFAULT NULL COMMENT '年龄',PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=12 DEFAULT CHARSET=utf8mb4 COMMENT='测试用户表';

在这里插入图片描述

.MYI 文件组织索引的方式就是 B+tree。叶子节点的 value 处存放的就是索引所在行的磁盘文件地址

在这里插入图片描述

底层查找过程

首先会判断查找条件 where 中的字段是否是索引字段,如果是就会先拿着这字段去 .MYI 文件里通过 B+tree 快速定位,从根节点开始定位查找;

找到后再把这个索引关键字(就是我们的条件)存放的磁盘文件地址拿到 .MYD 文件里面找,从而定位到索引所在行的记录。


表逻辑上相邻的记录行数据在磁盘上并不一定是物理相邻的。

在这里插入图片描述

存储引擎2: InnoDB

一张 InnoDB 表底层会对应2个文件在文件夹中进行数据存储。

.frm 文件(frame)存储表结构

.ibd 文件(InnoDB Data)存储表索引+数据

下面我创建了以 InnoDB 作为存储引擎的一张表 t_user_innodb。

CREATE TABLE `t_user_innodb` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',`name` varchar(50) DEFAULT NULL COMMENT '姓名',`age` int(3) DEFAULT NULL COMMENT '年龄',PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='测试用户表';

在这里插入图片描述

很显然,InnoDB 把索引和数据都放在一个文件里存着了。毫无疑问,InnoDB 表里面的数据也是用 B+tree 数据结构组织起来的。

下面我们来看看它具体是怎么存储的。

在这里插入图片描述

.ibd 存储数据的特点就是 B+tree 的叶子节点上包括了我们要的索引和该索引所在行的其它列数据

底层查找过程

首先会判断查找条件 where 中的字段是否是索引字段,如果是就会先拿着这字段去 .ibd 文件里通过 B+tree 快速定位,从根节点开始定位查找;

找到后直接把这个索引关键字及其记录所在行的其它列数据返回。

在这里插入图片描述

其他存储引擎:

我们在新建表的时候, 可以选择不同的存储引擎, 如下图: 其他引擎确实没有用过, 这里不再看了, 反正也用不到. 😂

在这里插入图片描述

索引

聚集(聚簇)索引

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

简单来说就是索引和它所在行的其它列数据全部都在一起了。

很显然,MyISAM 没有聚集索引,InnoDB 有,而且 InnoDB 的主键索引就是天然的聚集索引。

有聚集索引当然就有非聚集索引(稀疏索引)。对于 MyISAM 来说,它的索引就是非聚集索引。因为它的索引数据分开两个文件存的:一个 .MYI 存索引,一个 .MYD 存数据。

二级索引

除聚集索引之外的所有索引都叫做二级索引,也称辅助索引。

它的叶子节点则不会存储其它所有列的数据,就只存储主键值

在这里插入图片描述

底层查找过程

每次要找数据的时候,会根据它找到对应叶子节点的主键值,再把它拿到聚集索引的 B+tree 中查找,从而拿到整条记录。

在这里插入图片描述

优点:保持一致性和节省空间。

常见面试题

为什么 DBA 都建议表中一定要有主键,而且推荐使用整型自增?


注意:这里是推荐,没说一定。非要用 UUID 也不拦着你😁

为什么要有主键?

因为 InnoDB 表里面的数据必须要有一个 B+tree 的索引结构来组织、维护我们的整张表的所有数据,从而形成 .idb 文件。

那和主键有什么关系?

如果 InnoDB 创建了一张没有主键的表,那这张表就有可能没有任何索引,则 MySQL会选择所有具有唯一性并且不为 null 中的第一个字段的创建聚集索引。

如果没有唯一性索引的字段就会有一个隐式字段成为表的聚集索引:而这个隐式字段,就是 InnoDB 帮我们创建的一个长度为 6字节 的整数列 ROW_ID,它随着新行的插入单调增加,InnoDB 就以该列对数据进行聚集。

使用这个 ROW_ID 列的表都共享一个相同的全局序列计数器(这是数据字典的一部分)。为了避免这个 ROW_ID 用完,所以建议表中一定要单独建立一个主键字段。

为什么推荐使用整型自增?

首先整型的占用空间会比字符串,而且在查找比大小也会比字符串更。字符串比大小的时候还要先转换成 ASCII 码再去比较。

如果使用自增的话,在插入方面的效率也会提高。

不使用自增,可能时不时会往 B+tree 的中间某一位置插入元素,当这个节点位置放满了的时候,节点就要进行分裂操作(效率低)再去维护,有可能树还要进行平衡,又是一个耗性能的操作。

都用自增就会永远都往后面插入元素,这样索引节点分裂的概率就会小很多。

参考资料

https://mp.weixin.qq.com/s/36Jaj79Y8BxFoDB3Bwe7mg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/57085.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【flink】使用flink-web-ui提交作业报错

使用WebUI提交作业出现错误。 错误截图: 弹框信息: Server Response Message: org.apache.flink.runtime.rest.handler.RestHandlerException: Could not execute application.at org.apache.flink.runtime.webmonitor.handlers.JarRunHandler.lambda$h…

【vim 学习系列文章 4 - vim与系统剪切板之间的交互】

文章目录 背景1.1.1 vim支持clipboard 检查1.1.2 vim的寄存器 上篇文章:【vim 学习系列文章 3 - vim 选中、删除、复制、修改引号或括号内的内容】 背景 从vim中拷贝些文字去其它地方粘贴,都需要用鼠标选中vim的文字后,Ctrlc、Ctrlv&#x…

GD32F103VET输出PWM波形

GD32F103VET将TIMER0_CH3映射到PE14引脚,使其输出PWM波形。测试时,使用示波器看PE14引脚输出的波形,效果更直观。 TIMER0之PWM输出引脚映射如下: TIMER0_REMAP[1:0]"00"(没有映射): TIMER0_CH0默认被映射到PA8引脚 TIMER0_CH1默认…

Grafana V10 告警推送

最近项目建设完成,一个城域网项目,相关zabbix和grafana展示已经完,想了想,不想天天看平台去盯网络监控平台,索性对告警进行分类调整,增加告警的推送,和相关部门的提醒,其他部门看不懂…

大数据分析案例-基于随机森林算法构建多发性硬化症预测模型

🤵‍♂️ 个人主页:艾派森的个人主页 ✍🏻作者简介:Python学习者 🐋 希望大家多多支持,我们一起进步!😄 如果文章对你有帮助的话, 欢迎评论 💬点赞&#x1f4…

HIVE优化之不需要参数优化

#1.数据倾斜 什么是数据倾斜? 一部分数据多 一部分数据少 造成的结果: MR运行过慢 主要是shuffle和reduce过程慢 分组聚合导致数据倾斜 Hive未优化的分组聚合 方法1:在MAP端直接聚合(分组聚合优化),减少…

STDF - 基于 Svelte 和 Tailwind CSS 打造的移动 web UI 组件库,Svelte 生态里不可多得的优秀项目

Svelte 是一个新兴的前端框架,组件库不多,今天介绍一款 Svelte 移动端的组件库。 关于 STDF STDF 是一个移动端的 UI 组件库,主要用来开发移动端 web 应用。和我之前介绍的很多 Vue 组件库不一样,STDF 是基于近来新晋 js 框架 S…

echarts绘制甘特图

说在前面 项目上有需求,需要在大屏上展示进度甘特图,调研了DHTMLX和普加甘特图,效果都不是特别符合需求现状,查询了一些博客,决定使用echarts来绘制甘特图。 实现效果展示 实现思路分析 1、应该采用柱状图&#xff…

关于Java的IO流开发

IO概述 回想之前写过的程序,数据都是在内存中,一旦程序运行结束,这些数据都没有了,等下次再想使用这些数据,可是已经没有了。那怎么办呢?能不能把运算完的数据都保存下来,下次程序启动的时候&a…

[自动化测试] 读取CSV 文件

CSV文件可以用来存储固定字段数据,可以通过excel 表格另存为csv文件,不要直接改文件名称创建,不是真正的csv文件 import csv import codecs from itertools import islice #读取本地csv文件 datacsv.reader(codecs.open(filename./data/us…

探讨|使用或不使用机器学习

动动发财的小手,点个赞吧! 机器学习擅长解决某些复杂问题,通常涉及特征和结果之间的困难关系,这些关系不能轻易地硬编码为启发式或 if-else 语句。然而,在决定 ML 是否是当前给定问题的良好解决方案时,有一…

MySQL—— 基础语法大全

MySQL—— 基础 一、MySQL概述1.1 、数据库相关概念1.2 、MySQL 客户端连接1.3 、数据模型 二、SQL2.1、SQL通用语法2.2、SQL分类2.3、DDL2.4、DML2.5、DQL2.6、DCL 三、函数四、约束五、多表查询六、事务 一、MySQL概述 1.1 、数据库相关概念 数据库、数据库管理系统、SQL&a…