TEXT 和 BLOB 类型的使用注意事项

TEXT 和 BLOB 类型的使用注意事项

什么是 TEXT 和 BLOB

MySQL 中,TEXT 和 BLOB 是用于存储大量数据的字段类型。TEXT 系列用于存储字符串(字符数据),BLOB 系列用于存储二进制数据(图片、文件等)。它们各自有四个子类型,区别在于存储容量:

类型 最大长度
TINYTEXT / TINYBLOB 255 字节
TEXT / BLOB 65,535 字节(64KB)
MEDIUMTEXT / MEDIUMBLOB 16,777,215 字节(16MB)
LONGTEXT / LONGBLOB 4,294,967,295 字节(4GB)

TEXT 以字符为单位,受字符集影响;BLOB 以字节为单位,与字符集无关。

使用注意事项

1. 行溢出存储

InnoDB 中,TEXT/BLOB 字段通常存储在行外。当记录较大时,InnoDB 会在聚簇索引中保留一个 768 字节的前缀指针,实际数据存储在单独的溢出页中。这意味着:

  • SELECT 不查该字段时性能很好——不会读取溢出页
  • 一旦 SELECT 中包含该字段,即使只取一行,也要多一次 IO 读溢出页
  • 对于大字段频繁查询的场景,应考虑拆分到单独的表

2. 排序和索引限制

  • TEXT/BLOB 字段不能作为主键
  • 创建索引时必须指定前缀长度,比如 INDEX(column(100)),不能对全字段建索引
  • ORDER BY TEXT_COLUMN 排序时,只使用 max_sort_length 指定的前缀长度(默认 1024 字节),超出部分被截断
  • 使用 DISTINCTGROUP BY 时也会受此限制

3. 临时表与磁盘

  • 当查询需要对 TEXT/BLOB 字段排序或分组时,由于内存中的临时表无法容纳可变长度大字段,MySQL 会直接在磁盘上创建临时表
  • 这极大降低了性能,应避免对大字段进行排序或分组

4. 内存占用

  • 即使只查询 TEXT/BLOB 列的一小部分,MySQL 也可能读取整个值(取决于存储引擎和 buffer 大小)
  • 频繁访问大字段会增加 buffer pool 压力,挤占其他热数据的缓存空间

5. 字符集导致的容量差异

TEXT 类型的”最大字符数”定义在字符为单字节(如 latin1)时等于字节数,但如果是 UTF-8(utf8mb4),一个字符最多占 4 字节,实际能存的字符数就少了。设计表结构时要留意这一点。

6. 默认值限制

  • BLOB 和 TEXT 字段不能有默认值(MySQL 8.0.13 之前)
  • MySQL 8.0.13+ 允许为 TEXT/BLOB 设置默认值,但仅限表达式默认值

7. 避免使用 BLOB 存文件

  • 将大文件直接存 BLOB 会导致表体积膨胀、备份变慢、主从延迟增加
  • 建议只在数据库中存文件路径或对象存储的 URL,文件本身存文件系统或 OSS

8. 行格式影响

  • COMPACT 和 REDUNDANT 行格式:TEXT/BLOB 的前 768 字节存行内,剩余存溢出页
  • DYNAMIC 行格式(默认):根据长度决定是否完全行外存储
  • COMPRESSED 行格式:对溢出页进行压缩,节省空间但增加 CPU 开销

最佳实践

  1. 能不用就不用:能用 VARCHAR 解决的不要升级到 TEXT
  2. 放到单独表:如果业务上确实需要大字段,考虑垂直拆分到单独的扩展表
  3. 避免排序和分组:不要对 TEXT/BLOB 字段 ORDER BY 或 GROUP BY
  4. 只查询需要的字段:不要写 SELECT *,明确指定需要的列名
  5. 监控溢出页 IO:通过 SHOW ENGINE INNODB STATUS 观察溢出页的读写情况
  6. 选择合适的子类型:够用即可,TEXT 够用就选 TEXT,别一上来就 LONGTEXT
© 版权声明
THE END
喜欢就支持一下吧
点赞12 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容