在数据库中,CHAR 和 VARCHAR 是两种最常用的字符串存储类型,它们在存储机制、性能、空间利用和适用场景上存在显著差异。以下是基于核心特性的对比分析:
🔍 一、核心差异:存储机制
-
CHAR(定长字符)
• 固定分配空间:无论实际数据长度如何,均占用定义的全部空间。例如,CHAR(10) 存储 “abc” 时,会填充 7 个空格变为 "abc ",占用 10 字节(单字节字符集下)。• 尾部空格处理:插入时会自动删除末尾空格,检索时无尾部空格。
-
VARCHAR(变长字符)
• 按需分配空间:仅占用实际数据长度 + 长度标识字节。例如,VARCHAR(10) 存储 “abc” 时,占用 3 字节(数据)+ 1 字节(长度标识)= 4 字节(单字节字符集)。• 保留尾部空格:存储和检索时均保留原始空格。
💾 二、存储空间对比
类型 空间占用规则 最大长度限制
CHAR 始终等于定义长度(可能浪费空间)。例:CHAR(255) 固定占用 255 字节(单字节字符集)。 最大 255 字符(与编码无关)
VARCHAR 实际数据长度 + 1~2 字节(长度标识)。例:短文本更省空间,但超长文本需注意行限制。 最大 65,535 字节(受编码和行限制):
- UTF-8:约 21,844 字符(3 字节/字符)
- GBK:约 32,766 字符(2 字节/字符)
💡 空间效率:
-
固定长度数据(如 MD5 值)用 CHAR 无浪费。
-
变长数据(如用户评论)用 VARCHAR 节省空间。
⚡ 三、性能影响
类型 写入性能 读取性能
CHAR ✅ 更快:固定长度无需动态计算,直接写入固定位置。 ✅ 更快:直接按偏移量定位,无需解析长度标识。
VARCHAR ⚠️ 稍慢:需计算长度 + 动态分配空间(可能引发页分裂)。 ⚠️ 稍慢:需先读取长度标识再定位数据。
⚠️ 更新代价:
VARCHAR 字段若频繁更新且长度变化大(如地址修改),可能触发页分裂(Page Split),导致碎片化和性能下降。
🎯 四、适用场景
类型 推荐场景 典型案例
CHAR 数据长度固定或极短(≤255 字符),且需高频查询。 - 国家代码(CHAR(2))
- 性别标识(CHAR(1))
- 手机号(CHAR(11))
VARCHAR 数据长度波动大(如 10~1000 字符),空间敏感或更新不频繁。 - 用户名(VARCHAR(50))
- 地址(VARCHAR(200))
- 产品描述(VARCHAR(1000))
⚙️ 五、其他关键细节
- 索引效率
CHAR 的固定长度特性使其索引更紧凑,范围查询更快;VARCHAR 索引可能因长度波动效率略低。 - 字符编码影响
UTF-8 等变长编码下,CHAR(n) 仍按定义字符数分配空间(非字节数),但实际字节数随字符变化。 - 默认值处理
CHAR 和 VARCHAR 均可设默认值,但 TEXT 类型不可。
💎 六、选择建议
• 选 CHAR 当:数据长度完全固定(如身份证号)、高频查询且容忍少量空间浪费。
• 选 VARCHAR 当:数据长度变化 > 20%、存储空间敏感(如海量日志)、或字段更新频率低。
• 避免滥用:即使使用 VARCHAR,也应合理设定最大长度(如 VARCHAR(100) 而非 VARCHAR(255)),减少内存碎片。
例如存储用户昵称:
-
若 90% 数据在 10~20 字符间,用 VARCHAR(20);
-
若统一为 16 字符(如哈希值),用 CHAR(16)。