← 返回错误码列表

MySQL错误码 1118 分析与解决方案

错误信息

Error 1118

行大小太大。最大行大小(不包括BLOB)是65535字节。

你的MySQL表结构设计超出了行大小限制:

'pdo_code' => 'HY000',
'db_code' => 1118,
'db_error' => 'Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535.'

当前行大小已接近65,535字节的限制

解决方案

  • 使用VARCHAR代替CHAR类型字段
  • 将大字段改为TEXT或BLOB类型
  • 拆分表结构,将大字段移到单独的表
  • 使用行格式为DYNAMIC或COMPRESSED
  • 启用innodb_strict_mode=OFF(不推荐)
  • 优化字段长度,移除不必要的字段

表结构优化示例

-- 问题表结构(可能触发1118错误)
CREATE TABLE problem_table (
  id INT PRIMARY KEY,
  name CHAR(255),
  description CHAR(1000),
  address CHAR(500),
  -- 更多CHAR字段...
  created_at TIMESTAMP
);

-- 优化后的表结构
CREATE TABLE optimized_table (
  id INT PRIMARY KEY,
  name VARCHAR(255),
  description TEXT,
  address VARCHAR(200),
  created_at TIMESTAMP
) ROW_FORMAT=DYNAMIC;

行大小限制演示

MySQL行大小限制为65,535字节(不包括BLOB/TEXT类型):

问题表设计

使用多个 CHAR(255) 字段

每个CHAR字段占用255字节(即使内容为空)

20个CHAR(255)字段 = 5,100字节

优化方案

改用 VARCHAR(255) 字段

VARCHAR只占用实际内容长度 + 1-2字节

空VARCHAR字段只占用1字节

BLOB/TEXT优势

使用 TEXT 类型存储大内容

TEXT字段只占用9-12字节的行空间

实际内容存储在单独区域

预防措施

1. 字段类型选择

  • 优先使用VARCHAR而不是CHAR
  • 对大内容使用TEXT/BLOB类型
  • 合理设置字段长度
  • 避免过度使用ENUM/SET类型

2. 表结构设计

  • 使用行格式DYNAMIC或COMPRESSED
  • 考虑垂直分表(拆分大字段)
  • 定期审查表结构设计
  • 使用合适的字符集(utf8 vs utf8mb4)

3. 数据库配置

  • 设置innodb_file_format=Barracuda
  • 配置innodb_file_per_table=ON
  • 谨慎使用innodb_strict_mode=OFF
  • 监控表大小增长趋势

诊断工具

使用以下命令分析表结构:

# 查看表结构详情
SHOW CREATE TABLE table_name;

# 查看表行格式信息
SHOW TABLE STATUS LIKE 'table_name';

# 估算行大小
SELECT
  SUM(CHARACTER_MAXIMUM_LENGTH) AS total_char_size,
  COUNT(*) AS column_count
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'your_database'
  AND TABLE_NAME = 'your_table'
  AND DATA_TYPE LIKE '%char%';

行大小计算要点

CHAR字段:定义长度 × 字符集字节数

VARCHAR字段:实际长度 + 长度字节(1-2字节)

TEXT/BLOB:行内只存储指针(9-12字节)

NULL字段:额外占用1字节(每8个NULL字段)