
字符串字段选 VARCHAR 还是 TEXT,关键看数据长度、查询模式和索引需求,不是越长越安全,也不是越短越高效。
实际长度决定类型选择
VARCHAR(n) 适合长度可预期、通常较短的字段,比如用户名(VARCHAR(50))、邮箱(VARCHAR(255))、状态码(VARCHAR(20))。它只占用实际字符数 + 1~2 字节长度标识,存储效率高,且支持完整索引。
TEXT 类型(包括 TINYTEXT、TEXT、MEDIUMTEXT、LONGTEXT)适用于内容长度波动大、可能超 65535 字节的场景,如文章正文、日志内容、JSON 片段。但注意:MySQL 中 TEXT 默认不参与聚簇索引,也不能直接建全文索引以外的常规索引(除非指定前缀长度)。
- 若字段平均长度 VARCHAR(1000) 或更精准值
- 若字段经常存 > 10KB 的内容,或长度完全不可控,再考虑
MEDIUMTEXT - 避免为“以防万一”把所有文本字段都设成
TEXT——会损失索引能力与查询性能
索引与查询性能差异明显
VARCHAR 字段可直接创建完整长度索引(如 INDEX(name)),WHERE、ORDER BY、GROUP BY 都能高效利用。而 TEXT 字段建普通索引必须指定前缀,例如 INDEX(content(255)),这意味着只有前 255 字符参与索引匹配。
常见影响:
- 用
WHERE content = 'xxx'查询时,TEXT 无法走索引(除非加前缀且条件恰好匹配前缀部分) -
ORDER BY content在 TEXT 上会触发 filesort,速度慢且消耗临时表空间 - 联合索引中包含 TEXT 字段时,它只能放在最后,且仅前缀部分生效
行存储限制与溢出处理
InnoDB 表单行最大约 65535 字节(不含 BLOB/TEXT),VARCHAR 超过约 5600 字符后,内容可能被移至页外存储(off-page),但元信息仍留在主行;TEXT 则默认全部存为 off-page 指针 + 外部页,每次访问需额外 IO 查找。
这意味着:
- 高频读取短文本时,
VARCHAR的局部性更好,缓存命中率更高 - 大批量 SELECT * 查询含 TEXT 字段时,即使不用其内容,也会拉取外部页,拖慢响应
- 某些 ORM 或导出工具对 TEXT 类型处理不一致,容易出现截断或编码异常
现代替代方案值得考虑
如果业务需要灵活结构化文本(如配置、标签、属性),可评估:
- JSON 类型(MySQL 5.7+):支持索引提取路径、校验格式、原生函数操作
- 拆分设计:将高频检索字段单独建列(如
title,summary),长文本另存为MEDIUMTEXT - 外部存储:超大文本(如附件内容)改用对象存储,数据库只存 URL 和元数据
不复杂但容易忽略。










