大字段不应与主表绑定,否则导致查询慢、备份卡、索引失效;TEXT/BLOB需按实际大小和用途精准选型,避免滥用LONGTEXT;SELECT *应禁用,改用按需查询或SUBSTRING截取;前缀索引不适用模糊搜索,全文检索应依赖FULLTEXT或ES;优先垂直拆表或存文件路径,而非压缩或加密BLOB。

别把大字段和主表绑死,否则查询变慢、备份变卡、索引失效是必然结果。
TEXT/BLOB 类型选错会直接拖垮性能
MySQL 的 TEXT 和 BLOB 系列不是“随便选一个就行”。选错类型会导致字符集处理异常、无法排序、甚至插入失败。
-
TINYTEXT(255 字节)适合短说明、标签摘要;TEXT(64KB)够存一篇普通文章;MEDIUMTEXT(16MB)可放长文或小型 JSON;LONGTEXT(4GB)才适合整本电子书或日志快照 - 存纯文本用
TEXT,带字符集校验和排序能力;存图片、PDF、加密二进制流必须用BLOB,它不解释字节含义 - 别为了“以后可能变大”就直接上
LONGTEXT:InnoDB 对超大字段会强制 off-page 存储,哪怕只存 1KB,也可能触发额外 I/O
SELECT * 是大字段查询最常见踩坑点
只要表里有 TEXT 或 BLOB 字段,SELECT * 就等于主动放弃性能——哪怕你根本不需要那个字段。
- 高频接口中,把大字段从主查询剥离,改用按需 JOIN:
SELECT id, name, status FROM user+ 单独查SELECT content FROM user_profile WHERE user_id = ? - 真要读部分内容,用
SUBSTRING(content, 1, 1000)拿开头摘要,比全量加载快得多 - 应用层做缓存时,避免缓存含大字段的完整记录;缓存 key → 主键,内容单独查、单独过期
前缀索引不是万能解药,FULLTEXT 才是文本检索正解
INDEX(content(255)) 只能加速“以某前缀开头”的查询,对模糊匹配、关键词命中、分词搜索完全无效。
- 前缀长度必须实测:太短(如
content(10))区分度低,大量哈希冲突;太长(如content(1000))索引体积暴涨,反而拖慢写入 -
FULLTEXT索引专为TEXT设计,支持MATCH ... AGAINST,但仅限 MyISAM 或 InnoDB(5.6+),且不支持中文分词(需插件或外部引擎) - 真正需要全文检索又含中文?别硬扛:
TEXT字段只存原文,同步写入 Elasticsearch 或 Meilisearch,数据库只负责强一致性写入
拆表比压缩更可靠,文件路径比 BLOB 更可控
用 COMPRESS()/UNCOMPRESS() 看似省空间,但 CPU 开销翻倍、调试困难、备份恢复易出错——多数场景不如物理拆分。
- 垂直拆表最稳妥:
user表留id,name,email;user_bio表用user_id当主键 +bio LONGTEXT,加ON DELETE CASCADE - 文件路径方案更适合图片/附件:
user_avatar VARCHAR(255)存类似s3://bucket/users/123.jpg,由对象存储承担吞吐与 CDN - 如果必须加密存库内,别用应用层加密后塞
BLOB——用 MySQL 8.4+ 的AES_ENCRYPT()+ 列级加密(ENCRYPTION='Y'),避免密钥散落代码中
真正麻烦的从来不是“怎么存”,而是“什么时候该不存”。大字段一旦进入主业务流程,后续所有优化都像在给漏水的船补洞——先判断它是否真的属于数据库职责边界。


















