MySQL 行格式(ROW_FORMAT)详解
MySQL的行格式(ROW_FORMAT)是决定表中数据如何物理存储的重要设置,不同的行格式会影响存储效率、查询性能和特性支持。以下是MySQL行格式的全面解析。
一 MySQL行格式类型
行格式 | 引入版本 | 特性概述 | 适用场景 |
---|---|---|---|
REDUNDANT | 5.0之前 | 原始格式,兼容性好 | 需要兼容老版本 |
COMPACT | 5.0 | 节省20%存储空间 | 通用场景 |
DYNAMIC | 5.7 | 处理大文本/BLOB更高效 | 含大字段的表 |
COMPRESSED | 5.5 | 支持压缩存储 | 存储敏感场景 |
FIXED | - | 固定长度格式 | 已废弃 |
二 各格式详细对比
2.1 REDUNDANT格式
-- 创建使用REDUNDANT格式的表
CREATE TABLE t1 (id INT) ROW_FORMAT=REDUNDANT;
特点:
- 存储NULL值占用空间
- 列偏移量表占用更多空间
- 支持最大768字节的索引前缀
2.2 COMPACT格式
-- 默认行格式(当innodb_default_row_format=compact时)
CREATE TABLE t2 (id INT); -- 隐式使用COMPACT
优化点:
- NULL值不占存储空间(使用位图标记)
- 减少约20%的行头开销
- 仍限制索引前缀768字节
2.3 DYNAMIC格式
-- 推荐的新表默认格式
CREATE TABLE t3 (content LONGTEXT) ROW_FORMAT=DYNAMIC;
优势:
- 大字段(>40字节)完全off-page存储
- 索引前缀支持最长3072字节
- 更有效的溢出页管理
2.4 COMPRESSED格式
-- 创建压缩表
CREATE TABLE t4 (data VARCHAR(255)) ROW_FORMAT=COMPRESSED
KEY_BLOCK_SIZE=8;
压缩特性:
- 支持KEY_BLOCK_SIZE(1,2,4,8,16KB)
- 平均节省50%存储空间
- 需要额外CPU开销
三 行格式配置与管理
3.1 查看行格式
-- 查看表的行格式
SELECT table_name, row_format
FROM information_schema.tables
WHERE table_schema = '表名';-- 查看InnoDB默认行格式
SHOW VARIABLES LIKE 'innodb_default_row_format';
3.2 修改行格式
-- 修改现有表行格式
ALTER TABLE 表名 ROW_FORMAT=DYNAMIC;
3.3 配置默认行格式
# 在my.cnf中设置
[mysqld]
innodb_default_row_format=dynamic
四 行格式选择建议
4.1 通用场景选择
-- 推荐现代MySQL版本的默认选择
SET GLOBAL innodb_default_row_format='DYNAMIC';
4.2 特定场景选择
- 含TEXT/BLOB字段:必须使用DYNAMIC
- 存储空间敏感:COMPRESSED + 合适的KEY_BLOCK_SIZE
- 兼容老版本:COMPACT或REDUNDANT
4.3 注意事项
- 修改行格式需要重建表(锁表/耗时)
- COMPRESSED格式不支持ALTER TABLE…ADD COLUMN
- 系统表空间始终使用COMPACT格式
五行格式与索引限制
索引长度限制对比
行格式 | 索引前缀最大长度 |
---|---|
REDUNDANT | 768字节 |
COMPACT | 768字节 |
DYNAMIC | 3072字节 |
COMPRESSED | 3072字节 |
-- 当使用utf8mb4时计算可索引字符数
-- DYNAMIC格式: 3072/4 = 768个字符
-- COMPACT格式: 768/4 = 192个字符
六最佳实践
- 新项目统一使用DYNAMIC格式
-- 初始化数据库时设置 SET GLOBAL innodb_file_format=Barracuda; SET GLOBAL innodb_default_row_format=DYNAMIC;
注意:
参数innodb_file_format在8.0以上已经被删除;
参数innodb_default_row_format在5.7以上版本默认值是 DYNAMIC
-
压缩表使用建议
-- 对归档数据使用压缩 CREATE TABLE archive_data (id BIGINT PRIMARY KEY,payload JSON ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8;
-
监控表空间使用
-- 查看表空间使用情况 SELECT table_name, round(data_length/1024/1024,2) as data_mb,row_format FROM information_schema.tables WHERE table_schema NOT IN ('mysql','information_schema');
MySQL的行格式选择直接影响存储效率和查询性能,建议现代应用优先使用DYNAMIC格式,仅在特定场景考虑COMPRESSED格式。
更详细内容请查看官方文档:
https://dev.mysql.com/doc/refman/8.4/en/innodb-row-format.html
谨记:心存敬畏,行有所止。