Press "Enter" to skip to content

揭秘MySQL VARCHAR、TEXT与BLOB:不仅仅是长度的游戏

MySQL Logo

作为开发者,我们几乎每天都在和数据库打交道。在设计表结构时,一个经典的问题总是绕不开:“这个字段我应该用 VARCHAR(255) 还是 TEXT?” 很多人凭感觉选择了 VARCHAR,因为它似乎“更快”,或者因为大家都这么用。但你真的了解它们背后的巨大差异吗?

特别是当谈到长度限制时,VARCHARTEXTBLOB 都和数字 65,535 有关,这更加剧了混淆。

今天,我们就来彻底终结这个困惑,深入探讨它们的本质区别,并为你提供一份清晰的选型指南和MySQL数据类型速查表。

一、VARCHAR 的长度之谜:到底能存多少字符?

这可能是关于 VARCHAR 最令人困惑的问题。VARCHAR(L) 中的 L 到底代表什么?L 最大能设为多少?

答案比你想象的要复杂,它取决于两个关键因素:字节限制字符集

1. 理论上限:65,535 字节

MySQL 规定,一个 VARCHAR 列的最大长度是 65,535 字节 (Bytes)。注意,是字节,不是字符!

2. 字符集的影响

一个字符占用多少字节,完全由你选择的字符集(Character Set)决定:

  • latin1: 每个字符占用 1 个字节。
  • utf8 (实为 utf8mb3): 每个字符占用 1-3 个字节。
  • utf8mb4 (强烈推荐): 每个字符占用 1-4 个字节,可以存储 Emoji 表情。

因此,一个 VARCHAR 列能存储的最大字符数65,535 除以该字符集单个字符可能占用的最大字节数。

字符集 单字符最大字节数 VARCHAR列理论最大字符数
latin1 1 VARCHAR(65535)
utf8 3 VARCHAR(21845)
utf8mb4 4 VARCHAR(16383)

结论:在最常用的 utf8mb4 字符集下,VARCHAR 列最多可以定义为 VARCHAR(16383)

3. 行大小限制 (Row Size Limit)

还有一个更重要的限制:MySQL 中任何一行的总大小不能超过 65,535 字节

这意味着,即使 VARCHAR 理论上可以很大,但一张表中所有列(包括 VARCHARINTDATETIME 等)的数据加起来的总长度不能超过这个限制。如果你试图创建一个列总长度超过限制的表,MySQL 会直接报错。


二、终极对决:VARCHAR vs. TEXT vs. BLOB

既然它们都和 65,535 有关,那它们的区别到底在哪?核心区别在于存储方式和性能影响

简单来说:VARCHAR 的数据主要存在行内 (in-row),而 TEXTBLOB 的数据主要存在行外 (off-row)

特性 VARCHAR(L) TEXT BLOB
核心概念 可变长度字符串 可变长度长文本 可变长度二进制大对象
存储方式 行内存储。数据直接存在数据行里,查询时一次性读出。 行外存储。行内只存一个指向外部存储区域的指针,需要时再二次查找。 TEXT 相同,行外存储
长度限制 受整行大小限制。所有列加起来不能超过 65,535 字节。 自身数据限制TEXT 本身最大可存 65,535 字符,其大小不计入行大小限制(除了指针)。 BLOB 本身最大可存 65,535 字节。
长度定义 必须指定长度,如 VARCHAR(255) 无需指定长度,直接用 TEXT 无需指定长度。
索引能力 可创建完整索引。只要索引长度在限制内,可以对整个列建索引,查询效率高。 只能创建前缀索引,如 INDEX(content(100))。无法对全文进行高效索引。 TEXT 相同,只能创建前缀索引
数据类型 字符数据。受字符集和校对规则影响(如不区分大小写)。 字符数据。同 VARCHAR 二进制数据。原始字节流,没有字符集概念,比较时严格区分大小写。
DEFAULT 可以指定 DEFAULT 值。 新版MySQL可以,但通常不建议 新版MySQL可以,但通常不建议
内存使用 排序或创建临时表时,倾向于在内存中操作,效率高。 操作时,倾向于在磁盘上创建临时表,性能开销大。 TEXT 相同。

三、如何做出正确选择?一份实用的选型指南

场景 推荐类型 例子 理由
短的、长度可预知、需要索引 VARCHAR 用户名、邮箱、标题、订单号 性能好,可完整索引,查询快。
长的、不确定多长的文本内容 TEXT / MEDIUMTEXT / LONGTEXT 博客文章、商品描述、用户评论 不会撑爆行大小限制,适合存储大段文本。
非文本数据(文件、图片等) BLOB / MEDIUMBLOB / LONGBLOB 存储加密数据、序列化对象 专为二进制数据设计。

最佳实践: 除非你有特殊需求,否则不要在数据库中存储大文件(如图片、视频)。更好的做法是,将文件上传到对象存储服务(如 AWS S3、阿里云 OSS),然后在数据库的 VARCHAR 字段中只存储文件的 URL 或路径。


四、附录:MySQL常用数据类型速查表

为了方便你随时查阅,这里整理了一份常用数据类型的速查表。

1. 数值类型

类型 存储空间 范围 (有符号)
TINYINT 1 字节 -128 到 127
SMALLINT 2 字节 -32,768 到 32,767
INT 4 字节 -21亿 到 21亿
BIGINT 8 字节 约 -9.2 x 10¹⁸ 到 9.2 x 10¹⁸
DECIMAL(M,D) M+2 字节 精确小数,用于货币。
FLOAT 4 字节 单精度浮点数
DOUBLE 8 字节 双精度浮点数

2. 字符串类型

类型 长度/存储
CHAR(L) 固定长度,0-255字符
VARCHAR(L) 可变长度,0-65,535字节
TINYTEXT 最多 255 字符
TEXT 最多 65,535 字符
MEDIUMTEXT 最多 16M 字符
LONGTEXT 最多 4G 字符
TINYBLOB 最多 255 字节
BLOB 最多 64KB
MEDIUMBLOB 最多 16MB
LONGBLOB 最多 4GB

3. 日期和时间类型

类型 存储空间 格式 范围
DATE 3 字节 'YYYY-MM-DD' '1000-01-01' 到 '9999-12-31'
TIME 3 字节 'HH:MM:SS' '-838:59:59' 到 '838:59:59'
DATETIME 8 字节 'YYYY-MM-DD HH:MM:SS' '1000-01-01…' 到 '9999-12-31…'
TIMESTAMP 4 字节 'YYYY-MM-DD HH:MM:SS' '1970-01-01…' 到 '2038-01-19…' (UTC)
YEAR 1 字节 YYYY 1901 到 2155

4. JSON 类型

类型 描述
JSON 用于存储 JSON 文档,有专门的函数进行高效操作。

总结

选择正确的数据类型是数据库设计的基石。现在,你应该能清晰地理解:

  • VARCHAR 是为短的、需要索引的字符串设计的,其数据在行内,受行大小限制。
  • TEXTBLOB 是为大的数据块设计的,其数据在行外,不会影响行大小,但索引和内存操作性能较差。

下次设计数据库时,不要再凭感觉选择,而是根据你的数据特性和业务需求,做出最专业、最高效的决策!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注