“Data too long”错误根源在于字段定义的字节容量与当前连接字符编码不匹配:VARCHAR(255)在utf8mb4下最多占1020字节(255×4),而TEXT限制65535字节;需用DESCRIBE和SHOW CREATE TABLE确认字段实际字符集,再查@@character_set_client确保连接编码一致。

直接看字段定义和当前连接的字符编码,90% 的 “Data too long” 错误根源就在这两者不匹配。
查清楚字段定义的真实字节容量
MySQL 的 VARCHAR(255) 不代表能存 255 个中文——它代表最多 255 个「字符」,但每个字符占多少字节,取决于表/列的字符集。utf8mb4 下一个中文占 4 字节,所以实际字节上限是 255 × 4 = 1020 字节。而 TEXT 类型(如 TEXT)限制的是字节数:65535 字节,不是字符数。
- 用
DESCRIBE table_name;确认字段类型和长度 - 用
SHOW CREATE TABLE table_name;查看该列是否显式指定了CHARSET和COLLATE - 特别注意:即使表默认是
utf8mb4,单个列也可能被建表语句覆盖成latin1或utf8(旧版三字节 UTF-8)
确认当前连接的客户端编码
插入失败却手动执行 SQL 成功?大概率是客户端连接时用了不同编码。比如 SQL 文件保存为 UTF-8,但 mysql 命令行没指定 --default-character-set=utf8mb4,就会按服务器默认(可能是 latin1)解析文件,导致中文被错误解码、字节数膨胀,触发截断。
- 连接后立即执行
SELECT @@character_set_client, @@collation_connection; - 导入 SQL 文件时加参数:
mysql --default-character-set=utf8mb4 -u root -p db_name - Java 应用需在 JDBC URL 中显式声明:
?characterEncoding=utf8mb4&serverTimezone=UTC
别信“长度够用”的直觉,要算字节数
开发时看到 “描述只有 8 个汉字”,就以为 VARCHAR(255) 绝对安全——这是最危险的错觉。实际插入前,JDBC 驱动或 MySQL Server 会按当前连接编码把字符串转成字节流再校验长度。一个“?”字(Unicode 补充平面字符)在 utf8mb4 下占 4 字节,但某些生僻字或 emoji 可能触发更复杂的编码行为。
- 在 Java 中验证:
"系统显示名称".getBytes(StandardCharsets.UTF_8).length→ 得到真实字节数 - 在 MySQL 中模拟:
SELECT LENGTH('系统显示名称') AS char_len, LENGTH(CONVERT('系统显示名称' USING utf8mb4)) AS byte_len; - 如果应用层做截断,必须按字节截,不能用
substring(0, 255)——那截的是字符数,不是字节数
真正容易被忽略的是:同一个字段,在不同连接编码下,LENGTH() 返回值可能完全不同;而报错时提示的“超长”,永远是以当前 session 的字符集为准计算的字节数。不锁定 client/connection/tables/columns 四层编码一致性,光调大字段长度只是掩耳盗铃。


















