一、架构
整体概述
MySQL服务器是由连接池、服务管理工具和公共组件、NoSQL接口、SQL接口、解析器、优化器、缓存、存储引擎、文件系统组成。MySQL还为各种编程语言提供了一套用于外部程序访问服务器的连接器。整体架构图如下所示

MySQL Connectors:为使用 MySQL 服务的编程语言平台,提供了访问接口,可以根据自己实际使用的编程语言到官网下载地址下载。
MySQL Shell:是一个高级客户端和代码编辑器,以组件的形式提供,需要单独安装。除了提供的类似于 mysql 客户端的功能,还可以使用 JavaScript 和 Python 调用 MySQL 的 API,一般为开发人员使用。指的是 MYSQL 数据库的开发人员
连接层:对客户端连接进行权限校验并保存客户端的连接信息,通过池化技术实现线程重用,以及根据具体的配置限制连接数量。
服务管理和公共组件:提供了数据备份与恢复,安全组件,主从复制和集群管理,表分区等实用功能。
服务层:提供了 NoSQL API, SQL API, SQL 语句解析,SQL 语句优化,SQL 语句缓存等组件,并将优化后的 SQL 语句发送至存储引擎执行相应的操作并返回结果。
存储引擎层:一系列可插拔的存储引擎,主要负责数据的写入和读取,与底层的数据和日志文件进行交互,可以根据具体的业务需求选择不同的存储引擎,后面我们具体介绍他们之间的区别。
文件系统层:包含了 MySQL 发行版的文件和程序,以及具体数据库文件和日志。
连接层
负责客户端与 MySQL 的交互,管理连接和权限验证。

mysql是一个网络服务,通过ip+port就可以找到网络上指定的一个mysql服务
连接管理线程
通过连接管理器线程处理端口上的客户端连接请求:
在所有平台上,用一个管理器线程处理所有的 TCP/IP 连接请求。
在 Unix上,管理器线程还可以处理其他Unix socket 连接请求。
在 Windows 上,使用一个管理器线程处理通过Shared-memory方式连接请求,使用另一个管理器线程处理Named-pipe方式连接请求。
在所有平台上,可以额外启用一个端口用于接受针对管理的TCP/IP 连接请求,管理端口的连接可以使用处理"普通" TCP/IP 请求的管理器线程,也可以通过选项文件配置单独的线程。
客户端连接
连接管理器线程在接收到每个客户端连接后,把请求转发到真正的执行线程,每个请求都对应一个执行线程 ,该线程处理连接的身份验证和具体请求。执行线程使用线程池 技术进行缓存,当一个请求需要处理时,先从线程池中查找是否有可用的线程,如果没有则新创建一个,当连接结束时,如果线程池没有满,则把当前线程放入线程池,主要的作用是提高线程的复用,减少创建线程造成的系统开销从而提高效率。
可以通过以下几个系统变量和状态变量控制和监视服务器管理客户端连接的线程:
- 系统变量 thread_cache_size 决定了线程池缓存的大小。默认情况下,服务器在启动时会自动调整这个值,但也可以通过选项文件明确指定大小,值为0时禁用缓存,此时为每个新连接创建执行一个线程,并在连接断开时释放;
- 有些复杂的SOL语句在执行过程中可能会有深层递归从而消耗更多的内存,通过设置thread stack=N 调整线程堆栈大小;
- 要查看缓存中的线程数以及超过缓存数后新创建的线程数,通过状态变量Threads_cached 和Threads_created 查看;

bash
[mysqld]
mysqld节点thread_cache_size=16 #线程池大小
thread_stack=1048576 #堆栈内存大小
连接量管理
**1)**系统变量 max_connections 可以控制服务器允许同时连接的最大客户端数,当服务器达到max_connections 指定的连接数时会拒绝所有新的连接请求,同时会增加状态变量Connection_errors_max_connections 的值;
2) mysqld实际上允许 max_connections+1个客户端连接。额外的连接为拥有CONNECTION_ADMIN 权限的帐户(管理员)使用,即使普通连接达到了max_connections 的数量,管理员也可以连接到服务器进行管理操作;
**3)**在部署为主从复制的环境中,从节点的连接数也会计入 max_connections 中,如果连接达到上限主从复制将会失败;
**4)**max_connections 具体数据和服务器的硬件有关,比如可用的内存、每个连接消耗的内存,个的工作负载、响应时间、可用文件描述符的数量等等.
服务层
核心处理层,负责 SQL 解析、优化和执行。


服务管理与公共组件
- Backup&Recovery:备份与恢复
- Security:安全性与管理权限
- Replication:主从复制;
- Cluster:MySQL集群;
- Partitioning:表分区,用于在分库分表与表分区;
- Instance Manager:实例管理
- Administrator:MySQL管理员
- Migration Toolkit:迁移工具包
NOSOL接口与SOL接口
主要负责接收客户端发送的各种SOL语句和命令,并将SOL发送到其他部分,然后把接收到的结果返回给客户端。
Parser(语法分析器)
语法分析器的主要作用是将客户端发来的SQL语句中的关键字和自定义字段进行提取、解析,最终将 SQL语句转换为一棵解析树 ,分析的过程中包含词法分析和语法分析;
词法分析,主要是对关键字进行提取,比如 select/update/delete/create...;
语法分析,主要判断 SQL语句是否满足语法规则,如果语法错误则异出异常,也就是我们常见的ERROR1064(42000):Youhave anerror in your SQL syntax。
举例
sql
# 例如有如下SQL语句, 对应的解析树⼤致如图所⽰
select sn, name from student where id = 1;

0ptimizer(查询优化器)
通过语法校验的SQL语句将进入查询优化器处理阶段,查询优化器会将解析树转化为查询计划,一般情况下,一条查询可以有很多种执行方案,查询优化器会根据执行计划匹配合适的索引,选择最佳的执行方案,最终把确定要执行的SOL交给执行器调用存储引擎API。
优化后的SQL语句在条件查询时可能与程序员写的条件过滤顺序不同,但最终的返回结果一致
Caches& Buffers(缓存)
这里需要说明的是,缓存数据对应的数据在被更新之后将会失效,尤其在写多读少的场景中,缓存会频繁失效与新增,命中率非常低,因此MSOL5.6之后服务层缓存功能默认关闭,而且在MySOL8.0中服务层缓存被官方删除。
MVSOL的缓存主要的作用是为了提升查询的效率,当服务器接收到一个 select 查询语句时,会先进入缓存查询当前SOL语句在缓存中是否存在,缓存以key 和 value 的形式存储,key是具体的SOL语句,value是结果的集合,如果命中缓存,直接返回结果,无法命中缓存,则进入分析器进行正常查询流程。
SQL语句的执行流程

二、存储引擎
存储引擎是处理不同表类型SQL操作的MySQL组件。MySQL服务器采用可插拔的存储引擎架构,在服务器运行时可以动态的加载和卸载。
查看当前服务器支持哪些存储引擎可以使用 SHOW ENGINES 语句,Engine 表示:存储引擎的名称,Support:表示当前服务器是否支持,值分别为:YES、NO和 DEFAULT 分别表示,支持、不支持和当前设置或默认引擎,如下所示:

*InnoDB 存储引擎
核心特性(官网)
Feature | Support |
---|---|
B - tree indexes B+树索引 | Yes |
Backup/point - in - time recovery (Implemented in the server, rather than in the storage engine.) 备份与恢复 | Yes |
Cluster database support | No |
Clustered indexes 聚簇索引 | Yes |
Compressed data 数据压缩 | Yes |
Data caches 数据缓存 | Yes |
Encrypted data 数据加密 | Yes (Implemented in the server via encryption fur and later, data - at - rest encryption is supported.在服务器端通过加密实现,支持静态数据加密) |
Foreign key support 支持外键 | Yes |
Full - text search indexes 全文搜索 | Yes (Support for FULLTEXT indexes is available in ) |
Geospatial data type support 地理空间数据类型-经纬度 | Yes |
Geospatial indexing support 地理空间索引 | Yes (Support for geospatial indexing is available i later.) |
Hash indexes 内部使用自适应哈希索引 | No (InnoDB utilizes hash indexes internally for its Index feature.) |
Index caches 索引缓存 | Yes |
Locking granularity 锁的粒度 行级锁 | Row |
MVCC 多版本并发控制 | Yes |
Replication support (Implemented in the server, rather than in the storage engine.) 主从复制 | Yes |
Storage limits 存储的最大限制 | 64TB |
T - tree indexes | No |
Transactions 事务 | Yes |
Update statistics for data dictionary 更新数据字典的统计 | Yes |
*主要优势
1)DML 操作遵循 ACID 模型,事务具有提交、回滚和崩溃恢复功能,以保护用户数据。
DML 即数据操纵语言,它的作用是对数据库中的数据进行操作,常见的操作包括 INSERT(插入)、UPDATE(更新)、DELETE(删除)。DML 操作直接影响数据库中的数据内容。
2)如果发生意外而崩溃,无论当时数据库发生了什么,都不需要在重启数据库后执行任何特殊操作。InnoDB 的崩溃恢复功能会自动完成崩溃之前提交的更改,并撤消崩溃前正在进行但未提交的更改,从而允许我们从中断的地方继续执行。
3)支持行级锁 ,提高了多用户的读取并发性和性能。
4)InnoDB 存储引擎维护了一个自己的缓冲池,访问数据时在内存中缓存表和索引数据,对于经常使用的数据直接从内存中处理,大幅提升了效率。在专用数据库服务器上,通常会将高达 80% 的物理内存分配给缓冲池。
5)InnoDB 表优化了基于主键的查询,每个 InnoDB 表都有一个称为聚簇索引的主键索引,实现通过最少的磁盘 I/O 完成对主键的查找。
6)为了保持数据完整性,InnoDB 支持 FOREIGN KEY (外键) 约束。在进行插入、更新和删除数据时确保相关表之间的一致性
7)当从表中反复查询相同的行时,自适应哈希索引会自动接管这些查询,此时查询效率和哈希表相同。
最佳实践
- 为表中最频率查询的列(或多个列)指定主键(或复合主键),如果没有明显的主键,则创建一个自增的列做为主键。
- 从多个表中根据相同的ID查询数据,建议使用表连接。可以在连接的列上定义外键,并在每个表中使用相同的数据类型声明这些列。添加外键可以确保被引用的列使用索引,从而提高性能。
- 在每秒提交数百次事务的服务器上,结合存储设备的写入速度,关闭事务的自动提交,通过系统变量 autocommit=0FF 设置。
- 把相关的DML操作用START TRANSACTION和COMMIT语句括在一起,分组为事务一起提交或回滚。
- 不要使用 LOCK TABLES 语句,InnoDB可以在不牺牲可靠性和高性能的情况下处理多个会话同时对一个表进行读写操作。

如上图,InnoDB是默认的存储引擎,如果不是可以在选项文件中进行配置
bash
[mysqld] # 服务器节点下
default-storage-engine=InnoDB #明确指定InnoDB存储引擎
由于业务的实际需求不同,想要创建一个InnoDB表,可以通过这种方式
sql
CREATE TABLE table_name (
... 定义字段
) ENGINE = InnoDB; # 指定存储引擎
如果想测试使用其他存储引擎表中的数据在InnoDB表中的工作情况,在确保不影响原始表的情况下,使用以下方式创建一张InnoDB表
sql
CREATE TABLE ... ENGINE=InnoDB AS SELECT * FROM other_engine_table; #创建表并同时导入数据
创建InnoDB表
当创建一个引擎为InnoDB的表的时候,会在相应的数据目录下生成一个用来存储真实数据的物理文件,命名格式为 表名.ibd
sql
# 选择⽬标数据库
use test_db
# 创建⼀个使⽤InnoDB存储引擎的表
CREATE TABLE t_innodb (
id int(11) PRIMARY KEY AUTO_INCREMENT,
name varchar(20)
) ENGINE = InnoDB;

注意
- 在MySQL8.0中表结构的信息也保存在.ibd 文件中,可以使用 ibd2sdi 工具提取表定义的具体信息,使用方法:ibd2sdi --dump-file=t_innodb.txt t_innodb.ibd,生成的t_innodb.txt 文件中有对应表的具体描述
- sid=Serialized Dictionary Information 序列化字典信息
- 和8.0有所不同的是,在MySQL5.X及以前的版本中使用一个后缀为**.frm**的二进制文件来记录和描述表定义的信息
*MyISAM存储引擎
MyISAM是MySQL5.5之前默认的存储引擎,使用MyISAM存储引擎的表占用空间很小,但是由于使用表级锁定,所以限制了读/写操作的性能 ,通常用于中小型的Web应用和数据仓库配置中的只读或主要是读的场景。
MyISAM和InnoDB的主要区别
主要区别:MyISAM不支持外键,不支持事务,不支持哈希索引,锁粒度不同,单表的大小限制也不同(256TB),不支持崩溃自动恢复,需要手动恢复
主要优势
1)MyISAM 表的最大行数为 (2^32)^2 及 (1.844E+19) 行;
2)每个 MyISAM 表最多可以创建 64 个索引,每个索引最多可以包含 16 个列;MyISAM的非聚簇索引结构(B-Tree)在.MYI
文件中独立存储,每个索引需单独维护,限制索引数和列数可避免元数据膨胀。
3)支持并发插入;提升批量插入场景的吞吐量(如日志采集),但更新或删除操作仍会触发全表锁。
4)通过 CREATE table 创建表时,指定 DATA DIRECTORY=PATH 和 INDEX DIRECTORY=PATH 将数据文件和索引文件分开放置放在不同设备的不同目录中,从而提高访问速度;
5)BLOB 和 TEXT 数据类型的列也可以被索引(使用前缀索引,默认前1000字节,5.7之前MyISAM独占这一功能);
6)在索引列中允许使用 NULL 值,将其视为特殊值;
7)如果 mysqld 启动时设置了 myisam_recover_options 系统变量,那么 MyISAM 表在打开时进行会自查,如果上一次表没有正确关闭将会修复;
8)表中 VARCHAR 和 CHAR 列的长度总和最多可达 64KB,更适合宽表场景。
9)UNIQUE 约束的长度无限制
创建MyISAM表
sql
# 创建⼀个使⽤MyISAM存储引擎的表
CREATE TABLE t_myisam (
id int(11) PRIMARY KEY AUTO_INCREMENT,
name varchar(20)
) ENGINE = MyISAM;
创建 MyISAM 表会根据表名生成三个不同后缀名文件,分别是以**.MYD(MYData )为后缀的数据文件,以.MYI(MYIndex)为后缀的索引文件,以.sdi为后缀的表信息描述文件**(JSON格式,在8.0之前表信息的描述文件是以.frm为后缀的二进制文件)

表存储格式
MyISAM 表支持三种不同的存储格式,其中 FIXED 静态(固定)格式 和 DYNAMIC 动态格式 根据使用的列类型自动选择 ,第三种是压缩格式 ,只能使用 myisampack 实用程序生成并且是只读格式。
当表中没有 BLOB 或 TEXT数据类型的列,在使用CREATE TABLE或 ALTER TABLE 语句创建或修改表时,可以结合 ROWFORMAT表选项将表格式设置为FIXED或DYNAMIC
使用 myisamchk 实用工具对已压缩的MyISAM进行解压操作,myisamchk --unpack.
静态格式(Fixed-Length)表
1) 静态格式是 MyISAM 表的默认格式,当表不包含 可变长度的列(VARCHAR、VARBINARY.
BLOB 或 TEXT)时使用,每行都使用固定数量的字节存储。
2) MyISAM 的三种存储格式中**,静态格式是最简单和最安全的(最不容易损坏),同时也是最快的磁盘格式,因为每行的长度固定,根据索引中的行号乘以行长度就可以计算出行位置,此外,每次读取固定数量的行也非常的高效。**
**3)**静态格式表具有以下特点:
- CHAR和 VARCHAR 类型的列会用空格填充到指定的列宽;,BINARY和VARBINARY类型的列用 0x00 字节填充到列宽
- 每个允许为NULL的列,都用一个1BIT的额外空间记录当前列是否为空;0
- 速度非常快,且易于缓存;
- 崩溃后易于重建,因为行都位于固定位置;
- 通常需要比动态格式表更多的磁盘空间
动态格式表
**1)**当表中包含可变长度列 (VARCHAR、VARBINARY、BLOB 或 TEXT) 或者在创建表时使用 ROW_FORMAT=DYNAMIC 选项,则表格式为动态存储格式。
**2)**动态格式表具有以下特点:
- 列类型是字符串,且长度大于等于 4,长度都是动态的;
- 每一行都有一个标志来指示行有多长,当因更新操作而变得更长时,数据可能存储在不连续的空间,可以使用 OPTIMIZE TABLE table_name 语句或 myisamchk -r 对表进行碎片整理;
- 每个允许为 NULL 的列,都用一个 1 BIT 的额外空间记录当前列是否为空;
- 每行前面都有一个 bitmap (位图) ,用来记录包含空字符串或 0 的列,如果字符串类型的列长度为零,或者数字列的值 0,则在位图中标记并且不会保存到磁盘。

- 行中存储的是真实数据的长度,通常磁盘空间占用必固定长度表要少很多
- 每行都单独压缩,每列都可能用单独的方式进行压缩
**3)**常用的压缩方式
- 如果数值列的值为0,无论原始数据类型是哪种都用一个 BIT类型存储
- 如果整数列中的值范围较小,则尽可能使小的类型存储该列,比如:列中的值范围在-128到 127 之间,即使原始类型为 bigint(8bytes),也使用 TINYINT(1byte) 类型存储
- 如果列中只有一小组可能出现的值,则数据类型转换为ENUM(比如性别使用0,1,2)
压缩格式表
压缩格式表式使用myisampack工具生成的只读格式的数据表,压缩表可以使用myisamchk解压缩,具有以下特点:
- 压缩表占用很少的磁盘空间,最大限度地减少了磁盘使用;
- 可以用于固定长度或动态长度行
- 压缩表是只读的,因此不能在表中更新或添加数据:
MEMORY存储引擎
使用MEMORY引擎(以前叫HEAP)创建的表**,内容存储到内存之中**,当服务器由于硬件问题,断电或其他原因崩溃时数据会丢失,因此这些表只用于临时工作区或从其他表中提取数据的只读缓存。
使用场景
- 涉及瞬时、非关键数据的操作,例如会话管理或需要缓存的数据,当服务器停止或重新启动时,MEMORY 表中的数据会丢失;
- 用于快速访问和低延时,数据量可以完全放在物理内存中,不使用虚拟内存
- 只读或以读为主的数据访问场景(有限的更新)。
核心特点
**1)**使用固定长度的存储格式,可变长字符串,例如VARCHAR使用固定长度存储,
**2)**不能包含 BLOB或TEXT列
**3)**支持 AUTO_INCREMENT 的列
**4)**非 TEMPORARY MEMORY 表在所有客户端之间共享
**5)**支持 HASH 索引(默认)和 BTREE 索引
**6)**不支持表分区
7) 由于使用单线程且锁的粒度为表级锁,在高负载的场景下可能会涉及严重的锁竞争,特别是在多个客户端并发执行更新操作的情况下,官方说明:性能并不一定会比 InnoDB 更快。
创建MEMORY表
sql
# 创建⼀个使⽤MEMORY存储引擎的表
CREATE TABLE t_memory1 (
id int(11) PRIMARY KEY AUTO_INCREMENT,
name varchar(20)
) ENGINE = MEMORY;
由于数据在内存中保存,所以 MEMORY 表不会在磁盘上生成数据文件,表结构保存数据字典和.sdi 文件中

如果服务器重启了,表中的数据就没有了,那么重启之后表中的数据如何加载?
启动时填充 MEMORY 表的内容,可以使用 init_file 系统变量指定一个SQL文件,文件中可以编写用于初始化数据的SQL语句,例如:INSERT INTO ... SELECT或 LOAD DATA
内存管理
删除单行数据,不会回收内存,只有删除整个表时才会回收内存。当不需要内存表的内容时,要释放该表所使用的所有内存,可以执行 DELETE或TRUNCATE table 删除所有行,或者使用DROP table 删除表。如果要释放被删除行所使用的内存,使用ALTER TABLE ENGINE=MEMORY 命令强制重建表;
表中一行数据所需的内存使用以下表达式计算:
bash
# 涉及到所有BTREE索引⻓度、所有的HASH索引⻓度、单⾏数据⻓度
SUM_OVER_ALL_BTREE_KEYS(max_length_of_key + sizeof(char*) * 4)
+ SUM_OVER_ALL_HASH_KEYS(sizeof(char*) * 2)
+ ALIGN(length_of_row+1, sizeof(char*))
#ALIGN()函数的作用:使行长度为char类型大小的精确倍数
#sizeof(char*)在32位机器上是4,在64位机器上是8
max_heap_table_size 系统变量设置了内存表的最大大小限制,默认为16MB,要控制单个表的最大大小,在创建每个表之前设置该变量的 session 值。(不要改变全局的max_heap_table_size 值,除非要明确设置所有客户端创建的内存表)
sql
# 指定第⼀张表的内存最⼤值为1MB
mysql> SET max_heap_table_size = 1024*1024;
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE t1 (id INT, UNIQUE(id)) ENGINE = MEMORY;
Query OK, 0 rows affected (0.01 sec)
# 指定第⼆张表的内存最⼤值为2MB
mysql> SET max_heap_table_size = 1024*1024*2;
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE t2 (id INT, UNIQUE(id)) ENGINE = MEMORY;
Query OK, 0 rows affected (0.00 sec)
每次重启服务器内存表中的数据将被清空,内存表中的数据永远不会写入磁盘
CSV存储引擎
CSV(Comma - Separated Values)存储引擎将数据以纯文本的逗号分隔值(CSV)格式存储在文件中,便于与其他应用程序(如Excel、Python脚本)直接交互。但因其功能简单,仅适用于特定场景。
csv存储不支持索引,分区,且使用该引擎创建的表所有列必须为NOT NULL
创建CSV表
sql
mysql> CREATE TABLE t_csv (id INT NOT NULL, content CHAR(100) NOT NULL) ENGINE
= CSV;
Query OK, 0 rows affected (0.06 sec)
创建 CSV 表时,服务器会创建三个文件,其中以.CV 为扩展名的文件用于以逗号分隔值的格式保存数据;扩展名为.CSM 的文件,用于存储表的状态和表中的行数;以.sdi为后缀的表信息描述文件(JSON格式)

CSV表的修复与检查
CSV 存储引擎支持使用 CHECKTABLE和 REPAIR TABLE 语句来验证或修复损坏的 CSV
sql
mysql> CHECK TABLE t_csv; # 检查CSV表
+---------------+-------+----------+----------+
| Table | Op | Msg_type | Msg_text |
+---------------+-------+----------+----------+
| test_db.t_csv | check | status | OK |
+---------------+-------+----------+----------+
1 row in set (0.00 sec)
此时我们可以手动编辑.CSV文件,并且写入一条新数据
bash
root@zcy-vm:/var/lib/mysql/test_db# vim t_csv.CSV #编辑CSV文件
1,"record one"
2,"record two"
3,"record three" #手动写入一条新数据,保存并退出
但是此时在此查询语句,发现任然没有新增数据,这是因为.CSM文件中并没有记录新增的行,我们以可以使用repair table来修改表的内容和CSM文件
sql
mysql> REPAIR TABLE t_csv; # 修复CSV表
+---------------+--------+----------+----------+
| Table | Op | Msg_type | Msg_text |
+---------------+--------+----------+----------+
| test_db.t_csv | repair | status | OK |
+---------------+--------+----------+----------+
1 row in set (0.01 sec)
# 再次查询时,发现⼿动写⼊的记录显⽰出来了
mysql> select * from t_csv;
+----+--------------+
| id | content |
+----+--------------+
| 1 | record one |
| 2 | record two |
| 3 | record three |
+----+--------------+
3 rows in set (0.00 sec)
如果表损坏,在检查表的时候会报错误,例如将.CSV的文件,删除一部分内容,此时
bash
root@zcy-vm:/var/lib/mysql/test_db# vim t_csv.CSV #编辑
1,"record one"
2,"record two"
3 # 删除内容,构造⼀个错误格式的CSV数据
此时检查
sql
mysql> CHECK TABLE t_csv;
+---------------+-------+----------+----------+
| Table | Op | Msg_type | Msg_text |
+---------------+-------+----------+----------+
| test_db.t_csv | check | error | Corrupt |
+---------------+-------+----------+----------+
1 row in set (0.00 sec)
此时修复,错误的数据会被删除,且在修复期时,只有从 CSV文件第一行到第一个损坏行的行被复制到新表中,从第一个损坏的行到表末尾的所有其他行都会被删除,即使是有效数据。
Archive存储引擎
Archive存储引擎 专为高压缩率、低访问频率的归档数据 设计,适用于存储历史日志、审计记录等无需频繁修改的数据。其核心特点是通过高效的压缩算法减少存储空间占用,但牺牲了部分操作灵活性(如更新、删除)。
核心特性
1)支持 INSERT,REPLACE和 SELECT ,但不支持DELETE 和 UPDATE;
2)支持列的 AUTO_INCREMENT 属性,该列可以有唯一约束,且手动指定的值不能小于该列的最大值;
3)不支持索引 ,在任何列上尝试建立索引都会报错,查询性能低;也不支持事务
4)插入时,数据将被压缩,ARCHIVE 引擎使用 zlib 无损数据压缩;INSERT 语句只是将数据写入压缩缓冲区并且根据需要刷新到磁盘,当执行SELECT 时会强制刷新缓冲区;
5)检索时,按需要进行解压缩,不支持行缓存;
6)SELECT操作执行全表扫描,找出当前查询的行,并读取行数;
7)使用行级锁定
8)不支持表分区
创建表
sql
# 创建⼀个使⽤ARCHIVE存储引擎的表
CREATE TABLE t_archive (
id int(11) UNIQUE AUTO_INCREMENT,
name varchar(20)
) ENGINE = ARCHIVE;
创建 ARCHIVE 表会根据表名生成两个不同后缀名文件,分别是以.ARZ 为后缀的数据文件.sdi 为后缀的表信息描述文件(JSON格式),.ARN 文件在优化操作期间可能会出现。

BLACKHOLE存储引擎
BLACKHOLE存储引擎 (黑洞引擎)的设计目标是接收并丢弃所有写入的数据,如同"黑洞"一般,检索时,总是返回一个空结果。
核心特性
- BLACKHOLE 表不会存储任何数据,但如果启用了基于语句的二进制日志记录,则会记录 SOL语句并将其复制到副本服务器
- 支持索引
- 不支持分区
主要用途
BLICAKHOLE的主要应用在调优操作的场景
- 验证转储文件语法(mysqldump)
- 通过比较启用和不启用二进制日志记录的性能,测量二进制日志记录的开销
- 本质就是一个"无操作 "的存储引擎,可用于查找与存储引擎本身无关的性能瓶颈
创建表
创建 BLACKHOLE 表时,服务器会在全局数据字典中创建表定义并生成.sdi 为后缀的表信息描述文件;
sql
mysql> CREATE TABLE t_blackhole(id INT, content CHAR(10)) ENGINE = BLACKHOLE;
Query OK, 0 rows affected (0.03 sec)
mysql> INSERT INTO t_blackhole VALUES(1,'record one'),(2,'record two');
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> SELECT * FROM t_blackhole;
Empty set (0.00 sec)
MERGE存储引擎
MERGE存储引擎 (又称MRG_MyISAM )允许将多个结构相同的MyISAM表合并为一个逻辑表,简化跨表查询和数据管理。适用于VLDB(Very Large Data Bases大数据)环境,如数据仓库(现在已经有了更好的方案),这里的结构相同指的是所有的表中列具有相同的数据类型和索引信息。

创建表
sql
# 创建基础表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为后缀的表信息描述文件;


操作表
1)基础表中的 id 列作为 PRIMARY KEY 索引,但在MERGE表中并不作为主键,但是可以被索引。因为 MERGE 表不能对基础表集强制唯一性,类似的,基础表中具有 UNIQUE 索引的列可以在MERGE 表中被索引,但不能作为唯一约束,查询示例:


2)MERGE不支持全局的主键和唯一性校验,他的替代方案可以使用表分区
3)要将MERGE表重新映射到不同的MyISAM基础表集合,可以使用以下方法之一
- 删除MERGE表并重新创建;
- 使用 ALTER TABLE tbl name UNION=(..)修改基础表的集合:
4)使用 DROP TABLE只会删除MERGE表定义,基础MyISAM表不受影响。
FEDERATED存储引擎
federated -联邦的;联合的;结成同盟的
FEDERATED存储引擎允许MySQL客户端通过本地表访问远程服务器上的数据 ,实现跨数据库的透明查询。其核心机制是将本地表定义为远程表的代理,以多个物理服务器为基础创建一个所有操作(如SELECT、INSERT)通过MySQL客户端协议转发到远程服务器执行。

创建表
federated默认是关闭的,我们可以在配置文件中配置它
bash
# 配置⽂件路径 /etc/mysql/mysql.cnf
[mysqld]
federated=1 #加⼊配置
重启数据库

在远程环境先加入远程访问权限,创建基础表
sql
# 远程服务器上的建表语句
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;
本地服务器上建表
sql
# 本地服务器上的建表语句
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://federated:[email protected]:3306/test_db/t_federate
d'; # 指定远程服务器的连接
连接字符串的格式:
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服务器;
- 使用 CONNECTION 字符串时,密码中不能使用"@"字符,@前是用户名和密码,@后是主机信息
- DROP TABLE 只删除本地表,不删除远程表:
- 不支持事务
EXAMPLE存储引擎
EXAMPLE 存储引擎什么也不做,它的存在目的是为开发人员说明如何开始编写一个新的存储引擎,是MySQL源代码中的一个示例demo 。不支持索引和表分区。
当创建一个 EXAMPLE 表时,不会在磁盘上创建任何文件,表中不能存储任何数据,查询时始终返回一个空结果。
sql
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)
愿望是半个生命,淡漠是半个死亡。 ------纪伯伦
🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀
以上,就是本期的全部内容啦,若有错误疏忽希望各位大佬及时指出💐
制作不易,希望能对各位提供微小的帮助,可否留下你免费的赞呢🌸