MySQL Logo

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

特别是当谈到长度限制时,VARCHAR、TEXT 和 BLOB 都和数字 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列理论最大字符数
latin11VARCHAR(65535)
utf83VARCHAR(21845)
utf8mb44VARCHAR(16383)
结论:在最常用的 utf8mb4 字符集下,VARCHAR 列最多可以定义为 VARCHAR(16383)。

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

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

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


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

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

简单来说:VARCHAR 的数据主要存在行内 (in-row),而 TEXT 和 BLOB 的数据主要存在行外 (off-row)。
特性VARCHAR(L)TEXTBLOB
核心概念可变长度字符串可变长度长文本可变长度二进制大对象
存储方式行内存储。数据直接存在数据行里,查询时一次性读出。行外存储。行内只存一个指向外部存储区域的指针,需要时再二次查找。与 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. 数值类型

类型存储空间范围 (有符号)
TINYINT1 字节-128 到 127
SMALLINT2 字节-32,768 到 32,767
INT4 字节-21亿 到 21亿
BIGINT8 字节约 -9.2 x 10¹⁸ 到 9.2 x 10¹⁸
DECIMAL(M,D)M+2 字节精确小数,用于货币。
FLOAT4 字节单精度浮点数
DOUBLE8 字节双精度浮点数

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. 日期和时间类型

类型存储空间格式范围
DATE3 字节'YYYY-MM-DD''1000-01-01' 到 '9999-12-31'
TIME3 字节'HH:MM:SS''-838:59:59' 到 '838:59:59'
DATETIME8 字节'YYYY-MM-DD HH:MM:SS''1000-01-01…' 到 '9999-12-31…'
TIMESTAMP4 字节'YYYY-MM-DD HH:MM:SS''1970-01-01…' 到 '2038-01-19…' (UTC)
YEAR1 字节YYYY1901 到 2155

4. JSON 类型

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

总结

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

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

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