文章目录
- [4. 存储引擎](#4. 存储引擎)
-
- [4.5 ARCHIVE存储引擎](#4.5 ARCHIVE存储引擎)
-
- [4.5.1 ARCHIVE存储引擎的特性](#4.5.1 ARCHIVE存储引擎的特性)
- [4.5.2 创建ARCHIVE表](#4.5.2 创建ARCHIVE表)
- [4.6 BLACKHOLE存储引擎](#4.6 BLACKHOLE存储引擎)
-
- [4.6.1 BLACKHOLE存储引擎的特性](#4.6.1 BLACKHOLE存储引擎的特性)
- [4.6.2 BLACKHOLE存储引擎的用途](#4.6.2 BLACKHOLE存储引擎的用途)
- [4.6.3 创建BLACKHOLE表](#4.6.3 创建BLACKHOLE表)
- [4.7 MERGE存储引擎-合并](#4.7 MERGE存储引擎-合并)
-
- [4.7.1 创建MERGE表](#4.7.1 创建MERGE表)
- [4.7.2 操作MERGE表](#4.7.2 操作MERGE表)
- [4.8 FEDERATED 存储引擎](#4.8 FEDERATED 存储引擎)
-
- [4.8.1 创建FEDERATED表](#4.8.1 创建FEDERATED表)
- [4.8.2 FEDERATED表注意事项](#4.8.2 FEDERATED表注意事项)
- [4.9 EXAMPLE 存储引擎](#4.9 EXAMPLE 存储引擎)
- [4.10 其他存储引擎](#4.10 其他存储引擎)
- [4.11 不同存储引擎的特性](#4.11 不同存储引擎的特性)
- [5. 案例](#5. 案例)
-
- [5.1 创建一个数据库,并分别创建使用InnoDB引擎和MyISAM引擎的表](#5.1 创建一个数据库,并分别创建使用InnoDB引擎和MyISAM引擎的表)
- [6. 面试题](#6. 面试题)
4. 存储引擎
4.5 ARCHIVE存储引擎
使用
ARCHIVE存储引擎创建的表,存储大量不被索引的数据且占用空间很小,一般用于归档数据的存储。
4.5.1 ARCHIVE存储引擎的特性


- 支持
INSERT,REPLACE和SELECT,但不支持DELETE和UPDATE;- 支持列的
AUTO_INCREMENT属性,该列可以有唯一约束,且手动指定的值不能小于该列的最大值;- 不支持索引,在任何列上尝试建立索引都会报错;
- 插入时,数据将被压缩,
ARCHIVE引擎使用zlib无损数据压缩;INSERT语句只是将数据写入压缩缓冲区并且根据需要刷新到磁盘,当执行SELECT时会强制刷新缓冲区;- 检索时,按需要进行解压缩,不支持行缓存;
SELECT操作执行全表扫描,找出当前查询的行,并读取行数;- 使用行级锁定
- 不支持表分区
4.5.2 创建ARCHIVE表
- 在
MySQL 8.0中InnoDB是默认引擎,所以在创建表时需要指定ENGINE=ARCHIVE
mysql
# 创建一个使用ARCHIVE存储引擎的表
CREATE TABLE t_archive (
id int(11) UNIQUE AUTO_INCREMENT,
name varchar(20)
) ENGINE = ARCHIVE;

- 创建
ARCHIVE表会根据表名生成两个不同后缀名文件,分别是以.ARZ为后缀的数据文件,以.sdi为后缀的表信息描述文件(JSON格式),.ARN文件在优化操作期间可能会出现。
4.6 BLACKHOLE存储引擎
BLACKHOLE存储引擎就像一个"黑洞",接受数据,但不存储数据,检索时总是返回一个空结果。
4.6.1 BLACKHOLE存储引擎的特性
BLACKHOLE表不会存储任何数据,但如果启用了基于语句的二进制日志记录,则会记录SQL语句并将其复制到副本服务器- 支持索引;
- 不支持分区;
4.6.2 BLACKHOLE存储引擎的用途
- 验证转储文件语法
- 通过比较启用和不启用二进制日志记录的性能,测量二进制日志记录的开销;
- 本质上是一个 "无操作"的存储引擎,可用于查找与存储引擎本身无关的性能瓶颈
4.6.3 创建BLACKHOLE表
- 在
MySQL 8.0中InnoDB是默认引擎,所以在创建表时需要指定ENGINE=BLACKHOLE- 创建
BLACKHOLE表时,服务器会在全局数据字典中创建表定义并生成.sdi为后缀的表信息描述文件;
mysql
mysql> CREATE TABLE t_blackhole(id INT, content CHAR(10)) ENGINE = BLACKHOLE;
Query OK, 0 rows affected (0.01 sec)
mysql> INSERT INTO t_blackhole VALUES(1,'record one'),(2,'record two');
Query OK, 2 rows affected (0.01 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> SELECT * FROM t_blackhole; # 因为本质是一个无操作引擎
Empty set (0.00 sec)
mysql>

4.7 MERGE存储引擎-合并
MERGE存储引擎,也称为MRG_MyISAM引擎,允许MySQL DBA或开发人员在逻辑上将一系列相同的MyISAM表分组,并将它们作为一个对象引用。适用于VLDB(Very Large Data Bases)环境,如数据仓库。这里的相同表示所有表中的列都有相同的数据类型和索引信息。示意图如下:

4.7.1 创建MERGE表
- 在
MySQL 8.0中InnoDB是默认引擎,所以在创建表时需要指定ENGINE=MERGE- 创建
MERGE表必须指定UNION=(list-of-tables)选项,表示要使用哪些MyISAM表;还可以通过指定INSERT_METHOD选项来控制如何对MERGE表进行插入操作,FIRST或LAST值分别表示在第一个或最后一个基础表中进行插入,如果没有指定INSERT_METHOD选项,或者指定它的值为NO,那么在MERGE表中执行插入将会报错;
mysql
# 创建基础表1
mysql> CREATE TABLE test_m1 (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
content CHAR(20)) ENGINE=MyISAM;
# 创建基础表2
mysql> CREATE TABLE test_m2 (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
content CHAR(20)) ENGINE=MyISAM;
# 向基础表中写入数据
mysql> INSERT INTO test_m1 (content) VALUES ('Testing1'),('table1'),('test_m1');
mysql> INSERT INTO test_m2 (content) VALUES ('Testing2'),('table2'),('test_m2');
# 创建MERGE表
mysql> CREATE TABLE t_merge (
id INT NOT NULL AUTO_INCREMENT,
content CHAR(20), INDEX(id))
ENGINE=MERGE UNION=(test_m1,test_m2) INSERT_METHOD=LAST;
- 创建
MERGE表时,会在磁盘上创建一个.mrg文件,其中包含了基础MyISAM表的名称。MERGE的表格式存储在MySQL数据字典中;.sdi为后缀的表信息描述文件

mysql
root@yudukai:/var/lib/mysql/test_db# ll
total 652
drwxr-x--- 2 mysql mysql 4096 May 28 14:09 ./
drwx------ 10 mysql mysql 4096 May 28 00:00 ../
-rw-r----- 1 mysql mysql 114688 May 28 13:13 classes.ibd
-rw-r----- 1 mysql mysql 114688 May 28 13:13 course.ibd
-rw-r----- 1 mysql mysql 114688 May 28 13:13 score.ibd
-rw-r----- 1 mysql mysql 114688 May 28 13:13 student.ibd
-rw-r----- 1 mysql mysql 2775 May 28 13:53 t_archive_607.sdi
-rw-r----- 1 mysql mysql 88 May 28 13:53 t_archive.ARZ
-rw-r----- 1 mysql mysql 2414 May 28 14:04 t_blackhole_608.sdi
-rw-r----- 1 mysql mysql 2964 May 28 13:23 t_csv_606.sdi
-rw-r----- 1 mysql mysql 35 May 28 13:41 t_csv.CSM
-rw-r----- 1 mysql mysql 30 May 28 13:41 t_csv.CSV
-rw-r----- 1 mysql mysql 2776 May 28 14:09 test_m1_609.sdi
-rw-r----- 1 mysql mysql 255 May 28 14:09 test_m1.MYD
-rw-r----- 1 mysql mysql 2048 May 28 14:09 test_m1.MYI
-rw-r----- 1 mysql mysql 2776 May 28 14:09 test_m2_610.sdi
-rw-r----- 1 mysql mysql 255 May 28 14:09 test_m2.MYD
-rw-r----- 1 mysql mysql 2048 May 28 14:09 test_m2.MYI
-rw-r----- 1 mysql mysql 114688 May 27 20:45 t_innodb.ibd
-rw------- 1 root root 9468 May 27 20:50 t_innodb.txt
-rw-r----- 1 mysql mysql 4099 May 28 13:13 t_memory_605.sdi # 描述文件
-rw-r----- 1 mysql mysql 2779 May 28 14:09 t_merge_611.sdi # 磁盘文件
-rw-r----- 1 mysql mysql 36 May 28 14:09 t_merge.MRG
-rw-r----- 1 mysql mysql 2777 May 28 10:55 t_myisam_599.sdi
-rw-r----- 1 mysql mysql 0 May 28 10:55 t_myisam.MYD
-rw-r----- 1 mysql mysql 1024 May 28 10:55 t_myisam.MYI
root@yudukai:/var/lib/mysql/test_db# cat t_merge.MRG # 查看.MRG文件内容
test_m1
test_m2
#INSERT_METHOD=LAST
root@yudukai:/var/lib/mysql/test_db#
4.7.2 操作MERGE表
- 基础表中的
id列作为PRIMARY KEY索引,但在MERGE表中并不作为主键,但是可以被索引。因为MERGE表不能对基础表集强制唯一性,类似的,基础表中具有UNIQUE索引的列可以在MERGE表中被索引,但不能作为唯一约束,查询示例:
mysql
# 查询
mysql> select * from t_merge;
+----+----------+
| id | content |
+----+----------+
| 1 | Testing1 |
| 2 | table1 |
| 3 | test_m1 |
| 1 | Testing2 |
| 2 | table2 |
| 3 | test_m2 |
+----+----------+
6 rows in set (0.00 sec)
mysql>
要将
MERGE表重新映射到不同的MyISAM基础表集合,您可以使用以下方法之一:
删除
MERGE表并重新创建;使用
ALTER TABLE tbl_name UNION=(...)修改基础表的集合;
ALTER TABLE...UNION=()列表为空时,表示删除所有基础表使用
DROP TABLE只会删除MERGE表定义,基础MyISAM表不受影响。
4.8 FEDERATED 存储引擎
- 默认不支持,可以在启动时通过命令行选项
--federated或选项文件的配置来启用- 也是一个逻辑表,只定义表的结构,不存储真正的数据
mysql
mysql> show engines\G
... 省略
*************************** 4. row ***************************
Engine: FEDERATED
Support: NO
Comment: Federated MySQL storage engine
Transactions: NULL
XA: NULL
Savepoints: NULL
*************************** 5. row ***************************
... 省略
- 允许访问远程
MySQL数据库中的数据,在不使用复制或集群技术的情况下,FEDERATED存储引擎可以实现对远程MySQL数据库中数据的访问,以多个物理服务器为基础创建一个逻辑数据库,当查询FEDERATED表时,将会从远程数据库获取数据,非常适合分布式或数据集市环境。如图所示:

通过网络连接,真实数据保存在远程服务器上。
两个环境中的表定义是相同的。
4.8.1 创建FEDERATED表
本地配置文件中的
[mysqld]节点下加入federated=1来启用FEDERATED引擎,之后重启MySQL服务注意:
从 MySQL 8.0 开始,官方认为
FEDERATED引擎不够稳定和安全,所以在很多发行版的默认安装包中,干脆就没有包含这个插件文件。也就无法开启了。
mysql
# 配置文件路径 /etc/mysql/mysql.cnf
[mysqld]
federated=1 #加入配置
####################################################
# 重启MySQL服务
root@yudukai:/var/lib/mysql/test_db# systemctl start mysql
# 查看服务状态
root@yudukai:/var/lib/mysql/test_db# systemctl status mysql
● mysql.service - MySQL Community Server
Loaded: loaded (/lib/systemd/system/mysql.service; disabled; vendor preset: enabled)
Active: active (running) since Tue 2026-05-12 10:28:32 CST; 2 weeks 2 days ago
Main PID: 2658071 (mysqld)
Status: "Server is operational"
Tasks: 38 (limit: 9403)
Memory: 390.9M
CPU: 1h 56min 36.127s
CGroup: /system.slice/mysql.service
└─2658071 /usr/sbin/mysqld
Notice: journal has been rotated since unit was started, output may be incomplete.
root@yudukai:/var/lib/mysql/test_db#
- 重启本地数据库服务并查看
FEDERATED引擎是否启用
mysql
mysql> show engines\G
... 省略
*************************** 4. row ***************************
Engine: FEDERATED
Support: YES # 已经启用
Comment: Federated MySQL storage engine
Transactions: NULL
XA: NULL
Savepoints: NULL
- 在远程服务器上为用户加入远程访问权限,安全性与权限管理专题详细介绍
- 在
MySQL 8.0中InnoDB是默认引擎,所以在创建表时需要指定ENGINE=FEDERATED;- 创建
FEDERATED表时,本地的表定义与远程服务器的表定义相同,但数据存储在远程服务器上;- 本地表定义中使用
CONNECTION连接字符串指向远程表的连接字符串;
- 在远程环境创建基础表

mysql
# 远程服务器上的建表语句
CREATE TABLE t_federated (
id INT(20) PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(32) NOT NULL DEFAULT '',
INDEX name (name)
)
ENGINE=MyISAM
DEFAULT CHARSET=utf8mb4;
- 确认与远程服务器通信过程使用的用户名和密码,建议创建一个专业账户(下面软件是
MySQL Workbench)

然后授权

- 本地环境创建逻辑表
mysql
# 本地服务器上的建表语句
CREATE TABLE t_federated (
id INT(20) PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(32) NOT NULL DEFAULT '',
INDEX name (name)
)
ENGINE=FEDERATED
DEFAULT CHARSET=utf8mb4
CONNECTION='mysql://用户名:密码@192.168.100.242:3306/test_db/t_federated'; # 指定远程服务器的连接
# CONNECTION='mysql://user_name:password@host_name:port_num/db_name/tbl_name';
连接字符串的格式:
scheme://user_name[:password]@host_name[:port_num]/db_name/tbl_name
scheme: 连接协议,目前只支持mysql;user_name: 用于连接远程服务器的用户名,注意:这个用户在远程服务器已创建,并授予了相应的操作权限;password:用户的密码;host_name:远程服务器的IP地址;port_num:远程服务器MySQL服务的端口号;db_name: 远程表所在的数据库名;tbl_name:远程表名,本地表名与远程表名可以不同,但建议保持一致。- 不会生成数据文件,表定义在数据字典中,生成
.sdi为后缀的表信息描述文件(JSON格式)- 建表成功后,对本地表的增删改查和操作远程表一样
mysql
mysql> select * from t_federated; #查询
+----+----------+
| id | name |
+----+----------+
| 1 | zhangsan |
| 2 | lisi |
+----+----------+
2 rows in set (0.02 sec)
mysql> insert into t_federated values (3, 'wangwu'); #插入
Query OK, 1 row affected (0.01 sec)
mysql> select * from t_federated; #查询
+----+----------+
| id | name |
+----+----------+
| 1 | zhangsan |
| 2 | lisi |
| 3 | wangwu |
+----+----------+
3 rows in set (0.00 sec)
4.8.2 FEDERATED表注意事项
- 远程服务器必须是
MySQL服务器;- 使用
CONNECTION字符串时,密码中不能使用"@"字符;DROP TABLE只删除本地表,不删除远程表;- 不支持事务
4.9 EXAMPLE 存储引擎
EXAMPLE存储引擎什么也不做,它的存在目的是为开发人员说明如何开始编写一个新的存储引擎,是MySQL源代码中的一个示例。- 不支持索引和表分区
- 当创建一个
EXAMPLE表时,不会在磁盘上创建任何文件,表中不能存储任何数据,查询时始终返回一个空结果。
mysql
mysql> CREATE TABLE t_example (i INT) ENGINE = EXAMPLE;
Query OK, 0 rows affected (0.78 sec)
mysql> INSERT INTO t_example VALUES(1),(2),(3);
ERROR 1031 (HY000): Table storage engine for 'test' does not have this option
mysql> SELECT * FROM test;
Empty set (0.31 sec)
4.10 其他存储引擎
其他存储引擎或自定义存储引擎可以从实现了
Custom storage Engine接口的第三方和社区获取,Custom storage Engine接口是MySQL提供一的套API,至于如何开发一个存储引擎我们在这里不做过多讨论。
4.11 不同存储引擎的特性


注意事项:
- 在服务器中实现,而不是在存储引擎中实现。
- 仅在使用压缩行格式时支持压缩的
MyISAM表。使用MyISAM的压缩行格式的表为只读。- 通过服务器的加密函数实现。
- 通过服务器的加密函数实现;从
MySQL 5.7及以后版本支持静态数据加密。- 通过服务器的加密函数实现;从
NDB 8.0.22起支持加密的NDB备份;从NDB 8.0.29起支持透明的NDB文件系统加密。- 从
MySQL 5.6及以后版本支持FULLTEXT索引。- 从
MySQL 5.7及以后版本支持地理空间索引。InnoDB在内部利用哈希索引实现其自适应哈希索引功能。- 参见后续讨论。
5. 案例
5.1 创建一个数据库,并分别创建使用InnoDB引擎和MyISAM引擎的表
mysql
# 创建一个使用InnoDB存储引擎的表
CREATE TABLE t_innodb (
id int(11) PRIMARY KEY AUTO_INCREMENT,
name varchar(20)
) ENGINE = InnoDB;
# 创建一个使用MyISAM存储引擎的表
CREATE TABLE t_myisam (
id int(11) PRIMARY KEY AUTO_INCREMENT,
name varchar(20)
) ENGINE = MyISAM;
6. 面试题
- 说一下
MySQL的系统架构MySQL支持哪些存储引擎?- 介绍一下
InnoDB和MyISAM的区别