MySQL 单行数据的最大存储限制详解 MySQL 单行数据的最大存储限制并没有一个固定的数字。实际上,它更像是一个动态上限,由存储引擎、页大小、行格式、列类型这几个因素共同决定。下面这张图能帮你快速建立起直观印象。 InnoDB 行大小硬限制 官方文档定义 最大行大小:略小于 16KB 的页大小(
MySQL 单行数据的最大存储限制并没有一个固定的数字。实际上,它更像是一个动态上限,由存储引擎、页大小、行格式、列类型这几个因素共同决定。下面这张图能帮你快速建立起直观印象。
关键公式如下:
有效行大小 ≤ 16,384 - 页开销(~200B) - 系统列(13B) - 预留空间(~7,000B)
长期稳定更新的攒劲资源: >>>点此立即查看<<<
原因主要在于以下几项开销:
实测下来,单行总数据(不含溢出)在 MySQL 8.0 中基本就在 7,950 字节 附近。
当行数据超过阈值,InnoDB 会自动把大字段扔到溢出页里。具体来说:
| 列类型 | 溢出阈值 | 存储方式 |
|---|---|---|
| TEXT/BLOB | > 768 字节 | 主键页存 20 字节指针,数据存独立页 |
| VARCHAR | > 768 字节 | 同 TEXT |
| JSON | 总大小 > 768 字节 | 同 TEXT |
这意味着,逻辑行大小没有硬上限,只受限于 innodb_page_size 和磁盘空间。例如下面这张表,content 列可以存 4GB 数据:
CREATE TABLE t (
id INT PRIMARY KEY,
content LONGTEXT
);
主键页里只存 id 和 20 字节的指针,数据全在溢出页里分散存放。
| 类型 | 最大值 | 磁盘占用 |
|---|---|---|
| TINYINT | 1 字节 | 1B |
| INT | 4 字节 | 4B |
| BIGINT | 8 字节 | 8B |
| VARCHAR(N) | 65,535 字节 | 实际长度 + 1~2B 长度前缀 |
| TEXT | 65,535 字节 | 同 VARCHAR |
| MEDIUMTEXT | 16MB | 指针 + 溢出页 |
| LONGTEXT | 4GB | 指针 + 溢出页 |
| JSON | ≈ 1GB | 以 TEXT 形式存储 |
有一点必须注意:所有列的总和不能超过 65,535 字节,这是 MySQL 行格式本身限制,不是 InnoDB 说了算。
| 格式 | 溢出策略 | 适用场景 |
|---|---|---|
| COMPACT | > 768 字节溢出 | 旧版本兼容 |
| DYNAMIC | 所有大字段直接溢出 | 推荐!减少主键页碎片 |
| REDUNDANT | 已废弃 | — |
最佳实践就是直接使用 DYNAMIC 格式:
CREATE TABLE t (...) ROW_FORMAT=DYNAMIC;
尝试接近 8KB 的行:
CREATE TABLE max_row (
c1 VARCHAR(7000),
c2 VARCHAR(900)
) ROW_FORMAT=DYNAMIC;
INSERT INTO max_row VALUES (REPEAT('a',7000), REPEAT('b',900));
结果:成功,总大小约 7,900B。
存储 1GB 的 JSON:
CREATE TABLE huge_json (
id INT PRIMARY KEY,
data JSON
) ROW_FORMAT=DYNAMIC;
INSERT INTO huge_json VALUES (1, LOAD_FILE('/path/to/1gb.json'));
结果:成功,主键页里只有指针。
innodb_file_format=Barracuda 和 innodb_file_per_table=ON,建表时指定 ROW_FORMAT=DYNAMIC。SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES WHERE NAME='your_db/your_table'; 来查看溢出页的使用情况。ROW_FORMAT=DYNAMIC 配合拆分宽表,才能在容量和性能之间找到平衡。侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述