varchar(65535)建表失败,因整行非blob列字节总和(含字符集最大字节×n+长度标识2字节+变长/null元数据开销)必超65535限制;实际最大n取决于字符集:latin1为65533、utf8mb3为21844、utf8mb4为16383。

MySQL中VARCHAR字段的理论最大长度确实是65535,但**你几乎不可能在实际建表时成功声明VARCHAR(65535)**——它会直接报错。根本原因不是“设计上限”,而是行存储结构和字符集共同挤压出的硬性边界。
为什么VARCHAR(65535)建表会失败?
错误信息通常类似:Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535.。这说明限制不在单个VARCHAR列,而在整行所有非TEXT/BLOB列的**字节总和不能超过65535**。
这个65535里还要扣除两部分开销:
-
VARCHAR字段自身需要2字节存长度(所以理论上最多表示65535) - 每行还有「变长字段长度列表」和「NULL值列表」等元数据开销(至少1–2字节,随字段数增加)
也就是说,哪怕表里只有1个VARCHAR字段,也得给这些元数据留位置。所以VARCHAR(65535)在任何字符集下都必然超限。
VARCHAR(n)中n的实际最大值怎么算?
n是字符数,不是字节数。最终能写进表里的最大n,取决于字符集单字符最大字节数(Maxlen)和剩余可用字节数:
-
latin1(Maxlen=1):最大n = 65533(65535 − 2字节长度标识) -
utf8mb3(Maxlen=3):最大n = 21844(因为 21844 × 3 = 65532,再加2字节长度刚好65534) -
utf8mb4(Maxlen=4):最大n = 16383(16383 × 4 = 65532)
注意:MySQL在解析时会按Maxlen乘以n来预估最坏情况字节数,哪怕你只存ASCII字符,它也按4字节/字符算。
为什么不用TEXT替代超长VARCHAR?
当n逼近上述极限时,该列实际已不适合用VARCHAR:
-
TEXT类字段不计入65535行限制(只存指针,内容外置) -
VARCHAR过长会导致InnoDB把整行数据转为“溢出页”存储,反而降低查询效率 - 索引限制:
VARCHAR字段加索引时,前767字节(旧版本)或3072字节(开启innodb_large_prefix)是硬上限;而TEXT只能建前缀索引
如果你真需要存6万+字符,TEXT是更合理的选择,而不是死磕VARCHAR参数。
真正容易被忽略的点是:这个限制不是静态查文档就能避开的——它依赖当前表结构、字符集、甚至ROW_FORMAT(COMPACT vs DYNAMIC),必须在目标环境实测DDL才能确认临界值。











