文章目录
- [4. 存储引擎](#4. 存储引擎)
-
- [4.1 InnoDB 存储引擎](#4.1 InnoDB 存储引擎)
-
- [4.1.1 InnoDB存储引擎的特性](#4.1.1 InnoDB存储引擎的特性)
- [4.1.2 InnoDB 的主要优势](#4.1.2 InnoDB 的主要优势)
- [4.1.3 InnoDB表的最佳实践](#4.1.3 InnoDB表的最佳实践)
- [4.1.4 验证InnoDB是否为默认存储引擎](#4.1.4 验证InnoDB是否为默认存储引擎)
- [4.1.5 创建InnoDB表](#4.1.5 创建InnoDB表)
- [4.2 MyISAM 存储引擎](#4.2 MyISAM 存储引擎)
-
- [4.2.1 MyISAM 存储引擎的特性](#4.2.1 MyISAM 存储引擎的特性)
- [4.2.2 MyISAM 的主要优势](#4.2.2 MyISAM 的主要优势)
- [4.2.3 创建MyISAM 表](#4.2.3 创建MyISAM 表)
- [4.2.4 MyISAM 表存储格式](#4.2.4 MyISAM 表存储格式)
-
- [4.2.4.1 静态格式(Fixed-Length)表](#4.2.4.1 静态格式(Fixed-Length)表)
- [4.2.4.2 动态格式表](#4.2.4.2 动态格式表)
- [4.2.4.3 压缩格式表](#4.2.4.3 压缩格式表)
4. 存储引擎
存储引擎是处理不同表类型
SQL操作的MySQL组件。MySQL服务器采用可插拔的存储引擎架构,在服务器运行时可以动态的加载和卸载。查看当前服务器支持哪些存储引擎可以使用
SHOW ENGINES语句。
Engine表示:存储引擎的名称。Support:表示当前服务器是否支持,值分别为:YES、NO和DEFAULT分别表示,支持、不支持和当前设置或默认引擎。如下所示:
mysql
mysql> SHOW ENGINES\G
*************************** 1. row ***************************
Engine: ARCHIVE
Support: YES
Comment: Archive storage engine
Transactions: NO
XA: NO
Savepoints: NO
*************************** 2. row ***************************
Engine: BLACKHOLE
Support: YES
Comment: /dev/null storage engine (anything you write to it disappears)
Transactions: NO
XA: NO
Savepoints: NO
*************************** 3. row ***************************
Engine: MRG_MYISAM
Support: YES
Comment: Collection of identical MyISAM tables
Transactions: NO
XA: NO
Savepoints: NO
*************************** 4. row ***************************
Engine: FEDERATED
Support: NO
Comment: Federated MySQL storage engine
Transactions: NULL
XA: NULL
Savepoints: NULL
*************************** 5. row ***************************
Engine: MyISAM
Support: YES
Comment: MyISAM storage engine
Transactions: NO
XA: NO
Savepoints: NO
*************************** 6. row ***************************
Engine: PERFORMANCE_SCHEMA
Support: YES
Comment: Performance Schema
Transactions: NO
XA: NO
Savepoints: NO
*************************** 7. row ***************************
Engine: InnoDB
Support: DEFAULT
Comment: Supports transactions, row-level locking, and foreign keys
Transactions: YES
XA: YES
Savepoints: YES
*************************** 8. row ***************************
Engine: MEMORY
Support: YES
Comment: Hash based, stored in memory, useful for temporary tables
Transactions: NO
XA: NO
Savepoints: NO
*************************** 9. row ***************************
Engine: CSV
Support: YES
Comment: CSV storage engine
Transactions: NO
XA: NO
Savepoints: NO
9 rows in set (0.00 sec)
mysql>
4.1 InnoDB 存储引擎
InnoDB是一款兼顾高可靠性和高性能的通用存储引擎。在MySQL8.0中默认的存储引擎是InnoDB,使用CREATE TABLE语句创建表时,在没有修改默认存储引擎或明确指定其他存储引擎时,将创建一个InnoDB的表。
4.1.1 InnoDB存储引擎的特性

4.1.2 InnoDB 的主要优势
DML操作遵循ACID模型,事务具有提交、回滚和崩溃恢复功能,以保护用户数据。事务和锁专题中介绍- 如果发生意外而崩溃,无论当时数据库发生了什么,都不需要在重启数据库后执行任何特殊操作。
InnoDB的崩溃恢复功能会自动完成崩溃之前提交的更改,并撤消崩溃前正在进行但未提交的更改,从而允许我们从中断的地方继续执行。备份与恢复专题介绍- 支持行级锁,提高了多用户的读取并发性和性能。事务和锁专题中介绍
InnoDB存储引擎维护了一个自己的缓冲池,访问数据时在内存中缓存表和索引数据,对于经常使用的数据直接从内存中处理,大幅提升了效率。在专用数据库服务器上,通常会将高达80%的物理内存分配给缓冲池。InnoDB表优化了基于主键的查询,每个InnoDB表都有一个称为聚簇索引的主键索引(聚簇索引,主键索引,聚集索引是一个东西),实现通过最少的磁盘I/O完成对主键的查找。索引专题中介绍- 为了保持数据完整性,
InnoDB支持FOREIGN KEY(外键)约束。在进行插入、更新和删除数据时确保相关表之间的一致性- 当从表中反复查询相同的行时,自适应哈希索引会自动接管这些查询,此时查询效率和哈希表相同。
4.1.3 InnoDB表的最佳实践
- 为表中最频率查询的列(或多个列)指定主键(或复合主键),如果没有明显的主键,则创建一个自增的列做为主键。
- 从多个表中根据相同的
ID查询数据,建议使用表连接。可以在连接的列上定义外键,并在每个表中使用相同的数据类型声明这些列。添加外键可以确保被引用的列使用索引,从而提高性能。- 在每秒提交数百次事务的服务器上,结合存储设备的写入速度,关闭事务的自动提交,通过系统变量
autocommit=OFF设置。- 把相关的
DML操作用START TRANSACTION和COMMIT语句括在一起,分组为事务一起提交或回滚。- 不要使用
LOCK TABLES语句,InnoDB可以在不牺牲可靠性和高性能的情况下处理多个会话同时对一个表进行读写操作。其他的一些实践和优化我们在后面逐步介绍
4.1.4 验证InnoDB是否为默认存储引擎
- 执行
SHOW ENGINES语句查看可用的存储引擎时,查找SUPPORT列的值为DEFAULT的行
mysql
mysql> SHOW ENGINES\G #查看当前服务支持的存储引擎
*************************** 1. row ***************************
... 省略
*************************** 7. row ***************************
Engine: InnoDB
Support: DEFAULT
Comment: Supports transactions, row-level locking, and foreign keys
Transactions: YES
XA: YES
Savepoints: YES
*************************** 8. row ***************************
... 省略
mysql>
- 查询
Information Schema库中的ENGINES表
mysql
mysql> SELECT * FROM INFORMATION_SCHEMA.ENGINES\G
*************************** 1. row ***************************
... 省略
*************************** 7. row ***************************
ENGINE: InnoDB
SUPPORT: DEFAULT
COMMENT: Supports transactions, row-level locking, and foreign keys
TRANSACTIONS: YES
XA: YES
SAVEPOINTS: YES
*************************** 8. row ***************************
... 省略
mysql>
- 如果
InnoDB不是默认的存储引擎,可以通过在命令行指定选项--default-storageengine=InnoDB或者在选项文件的[mysqld]节点定义default-storageengine=InnoDB并重新启动服务器来设置InnoDB存储引擎
mysql
[mysqld] # 服务器节点下
default-storage-engine=InnoDB #明确指定InnoDB存储引擎
- 由于业务实际需要,服务器默认存储引擎不是
InnoDB时,想要创建一个InnoDB表,可以在使用CREATE TABLE语句创建表时明确指定InnoDB存储引擎,当然这样方式也可以指定其他任何支持的存储引擎
mysql
CREATE TABLE table_name (
... 定义字段
) ENGINE = InnoDB; # 指定存储引擎
- 如果想测试使用其他存储引擎表中的数据在
InnoDB表中的工作情况,在确保不影响原始表的情况下,使用以下方式创建一张InnoDB表
mysql
CREATE TABLE ... ENGINE=InnoDB AS SELECT * FROM other_engine_table;
4.1.5 创建InnoDB表
mysql
# 选择目标数据库
use test_db
# 创建一个使用InnoDB存储引擎的表
CREATE TABLE t_innodb (
id int(11) PRIMARY KEY AUTO_INCREMENT,
name varchar(20)
) ENGINE = InnoDB;
当创建一个存储引擎为 InnoDB 的表时,会在 data_dir/test_db 目录下生成一个用来存储真实数据的物理文件,命名格式为 表名.ibd ,以当前为例会在 /var/lib/mysql/test_db 目录下生成一个 t_innodb.ibd 的表空间数据文件。
mysql
root@yudukai:/var/lib/mysql/test_db# ll
total 120
drwxr-x--- 2 mysql mysql 4096 May 27 20:45 ./
drwx------ 10 mysql mysql 4096 May 27 20:45 ../
-rw-r----- 1 mysql mysql 114688 May 27 20:45 t_innodb.ibd # 表空间文件,存储表空间数据的文件
root@yudukai:/var/lib/mysql/test_db#
在
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的二进制文件来记录和描述表定义的信息

t_innodb.txt的内容:

4.2 MyISAM 存储引擎
使用
MyISAM存储引擎的表占用空间很小,但是由于使用表级锁定,所以限制了读/写操作的性能,通常用于中小型的Web应用和数据仓库配置中的只读或主要是读的场景。
4.2.1 MyISAM 存储引擎的特性


4.2.2 MyISAM 的主要优势
MyISAM表的最大行数为 (232)^2 及 (1.844E+19) 行;- 每个
MyISAM表最多可以创建64个索引,每个索引最多可以包含16个列;- 支持并发插入;
- 通过
CREATE table创建表时,指定DATA DIRECTORY=PATH和INDEX DIRECTORY=PATH将数据文件和索引文件放在不同设备的不同目录中,从而提高访问速度;BLOB和TEXT数据类型的列也可以被索引;- 在索引列中允许使用
NULL值;- 如果
mysqld启动时设置了myisam_recover_options系统变量,那么MyISAM表在打开时进行会自查,如果上一次表没有正确关闭将会修复;- 表中
VARCHAR和CHAR列的长度总和最多可达64KB。UNIQUE约束的长度不受限制
4.2.3 创建MyISAM 表
在
MySQL 8.0中InnoDB是默认引擎,所以在创建表时需要指定ENGINE=MyISAM:
mysql
# 创建一个使用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为后缀的二进制文件
mysql
root@yudukai:/var/lib/mysql/test_db# ll
total 140
drwxr-x--- 2 mysql mysql 4096 May 28 10:55 ./
drwx------ 10 mysql mysql 4096 May 28 00:00 ../
-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 2777 May 28 10:55 t_myisam_599.sdi # _599为自动生成的序号
-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#

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

4.2.4.3 压缩格式表
- 压缩存储格式是使用
myisampack工具生成的只读格式数据表,压缩表可以用myisamchk解压缩。- 压缩格式表具有以下特点:
- 压缩表占用很少的磁盘空间,最大限度地减少了磁盘使用;
- 可以用于固定长度或动态长度行
- 压缩表是只读的,因此不能在表中更新或添加数据;