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

【MySQL】存储引擎有哪些?区别是什么?

频率难度
60%⭐⭐⭐⭐

这个问题其实难度并不是很大,只是涉及到的相关知识比较繁杂,比如事务、锁机制等等,都和存储引擎有关系。有时还会根据场景选择不同的存储引擎。

下面笔者将会根据几个部分尽可能地讲清楚 MySQL 中的存储引擎,让你在面对这个问题时能够从容应对。

引言

在MySQL服务端处理客户端的请求时,到服务器程序完成了查询优化为止,还没有真正地去访问真实的表中数据,MySQL服务器把数据的存储和提取操作都封装到了一个名为存储引擎的模块中。

存储引擎

MySQL 中的数据通过不同技术存储在文件(或者内存)中,这些技术中的每一种技术都是用不同的存储机制、索引技巧、锁定级别等不同功能和能力,这袭人不同的技术以及配套的相关功能被称为存储引擎

存储引擎位于MySQL服务的第三层,如图示:

在物理上如何表示记录,怎么从表中读取数据以及怎么把数据写入具体的物理存储器上,都是存储引擎负责的事情。

为了实现不同的功能,MySQL 提供了不同的存储引擎,不同存储引擎管理的表可能有不同的存储结构,采用的存储算法也可能不同。我们可以根据自己的需求选择适用于服务器、数据库和表格的存储引擎。

存储引擎是数据库的核心,对于 MySQL 来说,存储引擎是以插件的形式运行的。

种类

MySQL 支持的存储引擎种类繁多,但是常用的就那么几种:MyISAM、InnoDB、MEMORY 等。

这里列出几个更多的存储引擎及其描述:

  • ARCHIVE:用于数据存档的引擎,数据被插入后就不能在修改了,且不支持索引。
  • CSV:在存储数据时,会以逗号作为数据项之间的分隔符。
  • BLACKHOLE:会丢弃写操作,该操作会返回空内容。
  • FEDERATED:将数据存储在远程数据库中,用来访问远程表的存储引擎。
  • InnoDB:具备外键支持功能的事务处理引擎
  • MEMORY:置于内存的表
  • MERGE:用来管理由多个 MyISAM 表构成的表集合
  • MyISAM:主要的非事务处理存储引擎
  • NDB:MySQL 集群专用存储引擎

MyISAM

使用这个存储引擎,每个 MyISAM 在磁盘上存储三个文件。

  1. frm 文件:存储表的定义数据
  2. MYD 文件:存放表具体记录的数据
  3. MYI 文件:存储索引

frm 和 MYI 可以存放在不同的目录下。MYI 文件用来存储索引,但有保存记录所在页的指针,索引的结构是 B+树 结构。

 从这张图可以发现,这个存储引擎通过 MYI 的 B+树 结构来查找页,再根据记录页查找记录。并且支持全文索引、B+树索引和数据压缩。

支持数据的类型也有三种:

  1. 静态固定长度表:这种方式的优点在于存储速度非常快,容易发生缓存,而且表发生损坏后也容易修复。缺点是占空间。这也是默认的存储格式。
  2. 动态可变长表:优点是节省空间,但是一旦出错恢复起来比较麻烦。
  3. 压缩表:上面说到支持数据压缩,说明肯定也支持这个格式。在数据文件发生错误的时候可以使用check table工具来检查,而且还可以使用repair table工具来恢复。

有一个重要的特点那就是不支持事务,但是这也意味着他的存储速度更快,如果你的读写操作允许有错误数据的话,只是追求速度,可以选择这个存储引擎。

InnoDB

InnoDB是默认的数据库存储引擎,它的主要特点有:

  1. 可以自动增长列,方法是 auto_increment 。
  2. 支持事务。默认的事务隔离级别为 可重复读,通过 MVCC(并发版本控制)来实现。
  3. 使用的锁粒度为行级锁,可以支持更高的并发。
  4. 支持外键约束,外键约束降低了表的查询速度,但是增加了表之间的耦合度。
  5. 配合一些热备工具,可以支持在线热备份。
  6. 在 InnoDB 中存在缓冲管理,通过缓冲池,将索引和数据全部缓存起来,加快查询的速度。
  7. 对于 InnoDB 类型的表,其数据的物理组织形式是聚簇表。所有的数据按照主键来组织。数据和索引放在一块,都位于 B+树 的叶子节点上。

InnoDB 的存储表和索引有下面两种形式:

  1. 使用共享表空间存储:所有表和索引存放在同一个表空间中。
  2. 使用多个表空间存储:表结构放在 frm 文件中,数据和索引放在 IBD 文件中。分区表的话,每个分区对应单独的 IBD 文件。

InnoDB 表必须要有聚集索引, 默认在主键字段上建立聚集索引,在没有主键字段的情况下,表的第一个非空的唯一索引将被建立为聚集索引。在两者都没有的情况下,InnoDB 将自动生成一个隐藏的自增 ID 列,并在此列上建立聚集索引。

文件结构为:

  • .frm 表定义文件
  • .ibd 索引数据文件

对于 InnoDB 来说,最大的特点在于支持事务。但是这是以损失效率来换取的。

Memory

将数据存储在内存中,为了提高数据的访问速度,每一个表实际上和一个磁盘文件关联。文件是 frm。

  1. 支持的数据类型有限制,比如不支持 TEXT 和 BLOB 类型,对于字符串类型的数据,只支持固定长度的行,VARCHAR 会被自动存储为 CHAR。
  2. 支持的锁粒度为表级锁。所以在访问量比较大时,表级锁会成为 Memory 存储引擎的瓶颈。
  3. 由于数据是存放在内存中的,一旦服务器出现故障,数据都会丢失。
  4. 查询的时候,如果有用到临时表,而且临时表中有 BLOB、TEXT 类型的字段,那么这个临时表就会转化为 MyISAM 类型的表,性能会急剧降低。
  5. 默认使用 hash 索引。
  6. 如果一个内部表很大, 会转化为磁盘表。

区别

不同的存储引擎都有各自的特点,以适应不同的需求,我们来看一下这几种存储引擎的区别:

功 能MYISAMMemoryInnoDBArchive
存储限制256TBRAM64TBNone
支持事物
支持全文索引
支持数索引
支持哈希索引
支持数据缓存N/A
支持外键

如何选择

存储引擎这么多,看着就让人头皮发麻, 我们怎么挑啊,其实大家多虑了,我们只需要掌握在开发中最常用的 InnoDB 和 MyISAM 就可以了,偶尔还会提一下 MEMORY。其中 MySQL5.5 之后默认的存储引擎是 InnoDB。

  • 大多数情况下,使用默认的 InnoDB 就对了,InnoDB 可以提供事务、行级锁、外键、B+ 树索引等能力。
  • MyISAM 适合读更多的场景。
  • MEMORY 适合临时表,数据量不大的情况。由于数据都存放在内存,所以速度非常快。

关于存储引擎的一些操作

查看存储引擎

# 查看当前的默认存储引擎:
mysql> show variables like "default_storage_engine";
# 查询当前数据库支持的存储引擎
mysql> show engines \G;

设置表的存储引擎

创建表示指定存储引擎

 如果没有指定表的存储引擎,就会使用默认的存储引擎,我们可以显式地指定,格式如下:

########################################
CREATE TABLE 表名(

建表语句

) ENGINE = 存储引擎名称;
########################################

# 示例
#创建表时指定存储引擎
create table engine_table_demo(id bigint(12),name varchar(200)) ENGINE=MyISAM; 
create table engine_table_demo2(id int(4),name varchar(50)) ENGINE=InnoDB;

修改表的存储引擎

如果已经建好的表,我们可以使用下面这个语句来修改表的存储引擎,格式如下:

#######################################
ALERT TABLE 表名 ENGINE = 存储引擎名称;
#######################################

# 示例
# 修改一个已经存在的表的存储引擎。
alter table test engine = innodb;

总结

存储引擎主要负责读取和写入底层表中的数据,MySQL 支持的存储引擎有好多种,它们的功能各有侧重,在选择存储引擎时,应该根据应用系统的特点选择合适的存储引擎。对于复杂的应用系统,还可以根据实际情况选择多种存储引擎进行组合。

我们常用的就是 InnoDB 和 MyISAM,其中 MySQL 5.5 之后默认的存储引擎是 InnoDB。

  • InnoDB:是Mysql的默认存储引擎,支持事务、外键。如果应用对事务的完整性有比较高的要求,在并发条件下要求数据的一致性,数据操作除了插入和查询之外,还包含很多的更新、删除操作,那么 InnoDB 存储引擎是比较合适的选择。
  • MyISAM:如果应用是以读操作和插入操作为主,只有很少的更新和删除操作,并且对事务的完整性、并发性要求不是很高,那么选择这个存储引擎是非常合适的(类似需求一般用mongoDB)。

🎉 如果这篇文章对你有帮助,点赞👍 收藏⭐ 关注✅ 哦,创作不易,感谢!😀 


http://www.kler.cn/a/513740.html

相关文章:

  • 【数据挖掘实战】 房价预测
  • Flink 使用 Kafka 作为数据源时遇到了偏移量提交失败的问题
  • golang接口
  • Excel 实现文本拼接方法
  • 【三维分割】Gaga:通过3D感知的 Memory Bank 分组任意高斯
  • 【Java】阿里环球Antom支付对接
  • CTTSHOW-WEB入门-爆破21-24
  • cnpm是什么鬼?
  • 视频m3u8形式播放 -- python and html
  • Python新春烟花
  • opencv-FindHomography接口-C语言实现
  • 靠右行驶数学建模分析(2014MCM美赛A题)
  • 日本IT|集成测试(結合テスト)的含义
  • office 2019 关闭word窗口后卡死未响应
  • 全新推理模型 DeepSeek-R1 问世,全面对标 OpenAI o1
  • “深入浅出”系列之C++:(10)nlohmann Json库
  • 【gopher的java学习笔记】Java中Mapper与Entity的关系详解
  • 虚拟mock
  • 学Python的人…
  • 【Spring Boot】Spring AOP动态代理,以及静态代理
  • 代码随想录刷题day13|(链表篇)24.两两交换链表中的结点
  • github无法访问配置
  • ubuntu24 springboot jar设置宕机重启
  • 【2024年华为OD机试】(C/D卷,200分)- 5G网络建设 (JavaScriptJava PythonC/C++)
  • Qt中自定义信号与槽
  • JAVA基础语句整理