【MySQL高阶】11.InnoDB存储引擎

文章目录

  • [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 :表示当前服务器是否支持,值分别为: YESNODEFAULT 分别表示,支持、不支持和当前设置或默认引擎。

如下所示:

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 TRANSACTIONCOMMIT 语句括在一起,分组为事务一起提交或回滚。
  • 不要使用 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=PATHINDEX DIRECTORY=PATH 将数据文件和索引文件放在不同设备的不同目录中,从而提高访问速度;
  • BLOBTEXT 数据类型的列也可以被索引;
  • 在索引列中允许使用NULL值;
  • 如果mysqld启动时设置了 myisam_recover_options 系统变量,那么MyISAM表在打开时进行会自查,如果上一次表没有正确关闭将会修复;
  • 表中 VARCHARCHAR 列的长度总和最多可达64KB
  • UNIQUE 约束的长度不受限制

4.2.3 创建MyISAM 表

MySQL 8.0InnoDB 是默认引擎,所以在创建表时需要指定 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 实用程序生成并且是只读格式。
  • 当表中没有 BLOBTEXT 数据类型的列,在使用 CREATE TABLE 或 ALTER TABLE 语句创建或修改表时,可以结合 ROW_FORMAT 表选项将表格式设置为 FIXEDDYNAMIC
  • 使用 myisamchk 实用工具对已压缩的MyISAM进行解压操作, myisamchk --unpack

4.2.4.1 静态格式(Fixed-Length)表
  • 静态格式是 MyISAM 表的默认格式,当表不包含可变长度的列 ( VARCHAR、VARBINARY 、BLOBTEXT ) 时使用,每行都使用固定数量的字节存储。
  • MyISAM 的三种存储格式中,静态格式是最简单和最安全的(最不容易损坏),同时也是最快的磁盘格式,因为每行的长度固定,根据索引中的行号乘以行长度就可以计算出行位置,此外,每次读取固定数量的行也非常的高效。
  • 静态格式表具有以下特点:
    • CHARVARCHAR 类型的列用空格填充到指定的列宽; BINARYVARBINARY 类型的列用 0x00 字节填充到列宽
    • 每个允许为NULL的列,都用一个 1 BIT 的额外空间记录当前列是否为空;
    • 速度非常快,且易于缓存;
    • 崩溃后易于重建,因为行都位于固定位置;
    • 通常需要比动态格式表更多的磁盘空间,因为填充了一定的宽度;

4.2.4.2 动态格式表
  • 当表中包含可变长度列( VARCHARVARBINARYBLOBTEXT )或者在创建表时使用ROW_FORMAT=DYNAMIC 选项,则表格式为动态存储格式

  • 动态格式表具有以下特点:

    • 列类型是字符串,且长度大于等于4,长度都是动态的;

    • 每一行都有一个标志来指示行有多长,当因更新操作而变得更长时,数据可能存储在不连续的空间,可以使用 OPTIMIZE TABLE table_name 语句或 myisamchk -r 对表进行碎片整理;

    • 每个允许为NULL的列,都用一个 1 BIT 的额外空间记录当前列是否为空;

    • 每行前面都有一个 bitmap (位图),用来记录包含空字符串或0的列,如果字符串类型的列长度为零,或者数字列的值0,则在位图中标记并且不会保存到磁盘;

    • 通常磁盘空间占用比固定长度表要少很多,因为行中记录的是真实数据的长度,不需要填充

    • 每行都单独压缩,每列都可能用单独的方式进行压缩。

  • 常用的压缩方式:

    • 如果数值列的值为0,无论原始数据类型是哪种都用一个 BIT 类型存储
    • 如果整数列中的值范围较小,则尽可能使小的类型存储该列,比如:列中的值范围在 -128127 之间,即使原始类型为 bigint (8bytes),也使用 TINYINT (1 byte) 类型存储
    • 如果列中只有一小组可能出现的值,则数据类型转换为 ENUM

位图:


4.2.4.3 压缩格式表
  • 压缩存储格式是使用myisampack工具生成的只读格式数据表,压缩表可以用 myisamchk解压缩。
  • 压缩格式表具有以下特点:
    • 压缩表占用很少的磁盘空间,最大限度地减少了磁盘使用;
    • 可以用于固定长度或动态长度行
    • 压缩表是只读的,因此不能在表中更新或添加数据;
相关推荐
wangbing11252 小时前
SQL Server2008 R2版自动备份问题
数据库
Trouvaille ~2 小时前
【Redis篇】Redis 渐进式遍历与数据库管理
数据库·redis·缓存·中间件·数据库管理·后端开发·scan
xcLeigh2 小时前
KES数据库运维监控与故障排查实战
运维·数据库·sql·故障排查·运维监控·kes
GlobalSign数字证书2 小时前
中小企业的 SSL/TLS 证书管理,有更轻量的方案
数据库·网络协议·ssl
梓䈑2 小时前
【MySQL】库的操作(数据库的创建、查看、修改 和 备份)
数据库·mysql
yuzhiboyouye2 小时前
原生 SQL 常用核心语句基础语法
数据库·sql·oracle
我是一颗柠檬2 小时前
【Redis】事务与Lua脚本Day7(2026年)
数据库·redis·后端·lua·database
流星白龙2 小时前
【MySQL高阶】14.MySQL存储结构
android·数据库·mysql
流星白龙2 小时前
【MySQL高阶】15.MySQL存储结构,页结构
android·mysql·adb