【MySQL高阶】13.其他存储引擎

文章目录

  • [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 , REPLACESELECT ,但不支持 DELETEUPDATE
  • 支持列的 AUTO_INCREMENT 属性,该列可以有唯一约束,且手动指定的值不能小于该列的最大值;
  • 不支持索引,在任何列上尝试建立索引都会报错;
  • 插入时,数据将被压缩, ARCHIVE 引擎使用 zlib 无损数据压缩; INSERT 语句只是将数据写入压缩缓冲区并且根据需要刷新到磁盘,当执行 SELECT 时会强制刷新缓冲区;
  • 检索时,按需要进行解压缩,不支持行缓存;
  • SELECT操作执行全表扫描,找出当前查询的行,并读取行数;
  • 使用行级锁定
  • 不支持表分区

4.5.2 创建ARCHIVE表

  • MySQL 8.0InnoDB 是默认引擎,所以在创建表时需要指定 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.0InnoDB 是默认引擎,所以在创建表时需要指定 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.0InnoDB 是默认引擎,所以在创建表时需要指定 ENGINE=MERGE
  • 创建MERGE表必须指定 UNION=(list-of-tables) 选项,表示要使用哪些MyISAM表;还可以通过指定 INSERT_METHOD 选项来控制如何对MERGE表进行插入操作, FIRSTLAST 值分别表示在第一个或最后一个基础表中进行插入,如果没有指定 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.0InnoDB 是默认引擎,所以在创建表时需要指定 ENGINE=FEDERATED
  • 创建 FEDERATED 表时,本地的表定义与远程服务器的表定义相同,但数据存储在远程服务器上;
  • 本地表定义中使用 CONNECTION 连接字符串指向远程表的连接字符串;
  1. 在远程环境创建基础表
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;
  1. 确认与远程服务器通信过程使用的用户名和密码,建议创建一个专业账户(下面软件是MySQL Workbench

然后授权

  1. 本地环境创建逻辑表
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 不同存储引擎的特性

注意事项:

  1. 在服务器中实现,而不是在存储引擎中实现。
  2. 仅在使用压缩行格式时支持压缩的 MyISAM 表。使用 MyISAM 的压缩行格式的表为只读。
  3. 通过服务器的加密函数实现。
  4. 通过服务器的加密函数实现;从 MySQL 5.7 及以后版本支持静态数据加密。
  5. 通过服务器的加密函数实现;从 NDB 8.0.22 起支持加密的 NDB 备份;从 NDB 8.0.29 起支持透明的 NDB 文件系统加密。
  6. MySQL 5.6 及以后版本支持 FULLTEXT 索引。
  7. MySQL 5.7 及以后版本支持地理空间索引。
  8. InnoDB 在内部利用哈希索引实现其自适应哈希索引功能。
  9. 参见后续讨论。

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 支持哪些存储引擎?
  • 介绍一下InnoDBMyISAM 的区别
相关推荐
薛定谔的悦1 小时前
光伏-储能-负荷联合预测:给 EMS 装上“预知能力“
java·数据库·人工智能·python·储能
阿演1 小时前
DataDjinn v0.1.6 更新:增加在线更新功能,Redis 数据源支持,表格预览和连接体验继续增强
数据库·redis·缓存·数据库连接工具
数据库小学妹1 小时前
InnoDB内存架构解密:Buffer Pool与性能优化实战
数据库·经验分享·sql·性能优化·架构
Lyyaoo.1 小时前
【MySQL】SQL优化
android·sql·mysql
AI人工智能+电脑小能手1 小时前
【大白话说Java面试题 第89题】【Mysql篇】第19题:Hash 索引和 B+ 树索引的区别?它们在使用方面的区别?
java·数据库·mysql·面试·哈希算法
ImTryCatchException1 小时前
Android 性能优化实战手册:从理论到落地的完整方法论
android·性能优化
一只fish1 小时前
Oracle官方文档翻译《Database Concepts 26ai》第17章-内存架构
数据库·oracle
sun0077001 小时前
qnx网络相关模块,全链路,硬件网卡 → 用户态驱动 (.so) → io‑pkt/io‑sock(用户态 TCP/IP + 转发 + 控制)
android
元宝骑士2 小时前
MySQL 实战:跨表排序 + 指定类型置顶四种写法
后端·mysql