MySQL 的 CHAR 和 VARCHAR 有什么区别?长度、字符集和存储怎么理解?
🧑💻 面试官:CHAR 固定长,VARCHAR 变长,VARCHAR(100) 最多存 100 字节,对吗?
🙋♂️ 我:对,超过 100 字节就放不下。
🧑💻 面试官:换成 utf8mb4,一百个中文字符也只占一百字节吗?
🙋♂️ 我:那 100 应该是字符数。
🧑💻 面试官:同样长度的尾部空格,存进去和比较时又一定按相同规则处理吗?
字符串要分开看三个问题:声明能放多少字符、实际占多少字节,以及保存和比较时怎样处理空格。
面试速答(60 秒版)
CHAR 和 VARCHAR 都用字符数声明长度,不是直接用字节数。CHAR 是固定字符长度语义,VARCHAR 按实际字符串长度保存,并需要长度信息;实际字节还取决于字符集和存储格式。
例如 utf8mb4 的一个字符最多需要四个字节,VARCHAR(100) 不等于最多一百字节。还要受到整行大小等限制。
CHAR 通常会补尾部空格,读取时尾部空格会被移除;VARCHAR 在有效长度内保存尾部空格。但字符串比较还由排序规则决定,不能从存储表现直接推导比较结果。
选型时,确实固定长度、允许这类空格语义的编码可以考虑 CHAR;名称、标题等长度变化明显的字段通常更适合 VARCHAR。不要简单说 CHAR 一定更快。

知识点详解:字符数、字节数和空格语义分别怎么判断
长度声明说的是字符,不是文件大小
假设同一个字段保存 AB、中文 和两个表情。它们的字符数量可能相同,编码后的字节数却不同。数据库字符和用户感知的一个字形也不总是一一对应,组合字符尤其要注意。
VARCHAR(100) 的 100 表示可声明的最大字符数。utf8mb4 允许一个字符最多四字节,并不是每个字符都固定四字节。
所以设计字段时,既要考虑用户输入长度,也要考虑字符集、行大小与索引字节限制。不能只拿产品要求的“100 个字”算磁盘空间。
固定长和变长,不要脱离字符集和行格式
为了看清基本区别,可以先假设单字节字符集:CHAR(4) 存 ab 会补到四字符长度,VARCHAR(4) 则保存实际两个字符,并带长度信息。
VARCHAR 的长度前缀是一或两字节,选择与该列可能需要的最大字节长度有关,不是只看当前字符串有多短。
这只是基本存储语义。InnoDB 的行格式、可变宽字符集和较长固定字段会影响实际物理存储。因此不要承诺任何 CHAR(n) 都精确占 n 字节,也不要用一个简单公式推算完整行大小。
保存空格,与比较空格,是两套规则
例如在有效长度内保存 ab 。VARCHAR 可以保留两个尾部空格;CHAR 的读取行为通常会去掉尾部空格。是否启用相关模式,要按实际版本和设置核实。
接下来比较 ab 与 ab 是否相等,还要看 collation 的 PAD SPACE 或 NO PAD 属性。VARCHAR 能保存空格,不代表比较时一定把空格当作差别。
如果字段要求逐字节保留和区分数据,比如协议字节或摘要,应考虑二进制类型及明确比较规则,而不是拿文本类型默认行为碰运气。
先按数据语义选,再测性能
固定长度地区码、标准代码,可以评估 CHAR;昵称、文章标题、描述等通常需要 VARCHAR 或其他合适文本类型。即使编码固定长,也要先确认尾部空格是否有意义。
字段声明过大还会影响某些执行过程中的空间估计,不能因为 VARCHAR 变长就随便全部写成最大值。
验证时在目标字符集、排序规则和严格模式下,测试长度边界、中文、表情和尾部空格。字段类型的实际表现,比“固定长更快”这个口号更值得说清楚。
本题机制参考:CHAR 与 VARCHAR、字符串存储、排序规则。
面试官继续追问
VARCHAR(100) 能不能放 100 个表情?
要看哪些字符、字段与行限制。单个支持的 Unicode 字符在 utf8mb4 中可占四字节;一个视觉表情也可能由多个字符组成,不能按图标数量直接判断。
超过长度一定会报错吗?
要结合严格模式和具体截断情形。对应用来说,应主动校验并处理数据库错误,不依赖静默截断。
唯一索引能区分大小写和尾空格吗?
取决于字段类型和排序规则。唯一性的比较语义也要核验,不能只凭 VARCHAR 或 CHAR 的名字决定。
面试速记卡
- 声明:CHAR(n)、VARCHAR(n) 的 n 是字符数。
- 字节:看字符集、内容与实际行格式。
- VARCHAR:实际内容加长度信息,不等于零开销。
- 空格:存储和比较要分开看。
- 选型:按数据语义与约束,不背固定长必快。
公司面试真题
这道题暂未收录可核验的公司真题来源。你可以先阅读本文解析,或浏览已收录的公司面试真题。
浏览公司面试真题 →