← 返回题目列表

MySQL 中 CHAR、VARCHAR 和 TEXT 有什么区别?

高频 中等 第 8 / 28 题 更新于 2026/07/29
MySQLCHARVARCHARTEXT字段类型

简化版

CHAR 是定长字符串,适合长度固定的数据;VARCHAR 是变长字符串,适合长度变化但有明确上限的字段;TEXT 用于较长文本,通常不适合作为频繁排序、过滤和索引的主字段。

详细版

CHAR(n) 会按固定长度存储,短内容可能补空格,适合国家码、状态码、MD5 这类长度稳定字段。VARCHAR(n) 按实际长度存储并额外记录长度,适合用户名、标题、邮箱等大多数业务字符串。

TEXT 面向长文本,长度上限更大,但默认值、索引长度、排序和临时表处理上往往有更多限制或成本。能用 VARCHAR 表达清楚上限时,不要随手把字段设成 TEXT

面试回答还要注意字符集。VARCHAR(100) 表示最多 100 个字符,不等于 100 字节;使用 utf8mb4 时,一个字符最多可能占 4 字节。

完整版教学

一、先区分定长和变长

CHAR 是定长,VARCHAR 是变长。定长意味着字段声明多长,存储和比较时就围绕这个固定长度处理;变长则会根据实际内容长度存储。

CREATE TABLE demo (
  code CHAR(6),
  name VARCHAR(50)
);

如果 code='CN'CHAR(6) 仍然按固定长度语义处理;如果 name='Tom'VARCHAR(50) 主要保存实际内容和长度信息。

记忆钩子:长度固定用 CHAR,长度浮动用 VARCHAR,大段正文才考虑 TEXT

二、CHAR 适合什么场景

CHAR 适合长度非常稳定的字段,比如性别编码、国家码、定长 hash、状态短码。

CREATE TABLE api_keys (
  id BIGINT PRIMARY KEY,
  md5 CHAR(32),
  country_code CHAR(2)
);

如果所有值都是 32 位 MD5,使用 CHAR(32) 语义清楚,长度固定也方便比较。若字段长度差异很大,例如昵称从 1 到 50 个字符都有,CHAR(50) 就会浪费空间。

假设 100 万行昵称平均 6 个字符,使用 CHAR(50) 会为短昵称付出明显额外空间;VARCHAR(50) 更合适。

三、VARCHAR 是业务字段主力

VARCHAR 适合有明确最大长度、但实际长度变化的字段。

CREATE TABLE users (
  id BIGINT PRIMARY KEY,
  nickname VARCHAR(50),
  email VARCHAR(255)
);

它会额外使用 1 或 2 个字节记录长度,具体取决于最大长度。这个额外成本通常比 CHAR 浪费大量填充空间更划算。

字段推荐类型原因
手机号VARCHAR(20) 或按规范设计可能有区号、加号
邮箱VARCHAR(255)长度变化明显
状态码VARCHAR 或短 CHAR看编码是否固定
标题VARCHAR(200)有上限且常过滤展示

设计 VARCHAR 时要给出业务上限,不要盲目写很大。

四、TEXT 的代价在哪里

TEXT 适合文章正文、评论内容、描述字段这类长文本。它的问题不在于不能用,而是不能滥用。

CREATE TABLE articles (
  id BIGINT PRIMARY KEY,
  title VARCHAR(200),
  content TEXT
);

长文本字段可能影响临时表、排序、网络传输和页存储。对 TEXT 建索引时通常需要指定前缀长度:

CREATE INDEX idx_content_prefix ON articles(content(100));

前缀索引只能利用前 100 个字符,区分度和查询语义都要谨慎评估。对于频繁过滤和排序的字段,应尽量使用有明确长度的 VARCHAR 或单独设计检索方案。

五、字符数和字节数不要混淆

VARCHAR(100) 中的 100 通常表示字符数上限,而实际存储会受字符集影响。

utf8mb4 下:

英文 A:通常 1 字节
常见中文:通常 3 字节
部分 emoji:可能 4 字节

所以 VARCHAR(100) 最多可能需要约 400 字节存储字符内容,再加长度字节等开销。

这对索引长度也有影响。复合索引中放多个长 VARCHAR 字段,可能让索引项变大,降低页容纳量和缓存效率。

六、字段类型会影响索引和排序

字符串字段越长,索引越大;索引越大,B+ 树节点能放的键越少,查询和缓存成本可能越高。

例如:

CREATE INDEX idx_title ON articles(title);

title VARCHAR(200) 通常合理;如果把标题设计为 TEXT 再建前缀索引,可能无法完整支持精确排序和唯一约束。

对需要频繁排序的字段:

SELECT id, title
FROM articles
ORDER BY title
LIMIT 20;

字段类型、长度、字符集和索引都会影响执行计划。类型设计不是表结构小事,它会一路影响查询性能。

七、常见误区与追问

  • 误区:VARCHAR 永远比 CHAR 好。 长度完全固定的字段用 CHAR 可能更清晰。
  • 误区:TEXT 更大,所以字段都用 TEXT 更省心。 TEXT 在默认值、索引、排序和临时表上成本更高。
  • 误区:VARCHAR(100) 就是 100 字节。 它通常表示 100 个字符,字节数取决于字符集。
  • 误区:字符串长度设计只影响存储空间。 它还影响索引大小、缓存命中和排序成本。
  • 追问:手机号用数字还是字符串? 通常用字符串,因为可能有前导 0、国家码和加号,不参与数值计算。
  • 追问:长文本要搜索怎么办? 不应只靠普通 LIKE '%xxx%',可评估全文索引或搜索引擎方案。

八、加强记忆

字符串类型题按“固定、变化、长文”来选:固定长度用 CHAR,业务字符串用 VARCHAR,文章正文类用 TEXT。再补上字符集和索引成本,答案就不只是背类型,而是能指导表设计。