在数据库中,VARCHAR
和 CHAR
都是用于存储字符串的数据类型,但它们在存储方式、空间占用和适用场景上有本质区别。以下是核心对比:
1. 存储方式与空间占用
特性 | CHAR | VARCHAR |
---|
存储方式 | 定长存储 | 变长存储 |
空间分配 | 固定长度(声明长度) | 实际数据长度 + 长度前缀(1-2字节) |
未用空间 | 用空格填充剩余长度,占用固定空间 | 仅存储实际数据,无空间浪费 |
示例 | CHAR(10) 存储 "abc" → 占用 10字节 | VARCHAR(10) 存储 "abc" → 占用 3字节+长度前缀 |
2. 性能对比
场景 | CHAR | VARCHAR |
---|
读取速度 | ✅ 更快(固定长度,直接定位) | ⚠️ 稍慢(需解析长度前缀) |
更新速度 | ⚠️ 若新数据长度不变则快,否则需重写整行 | ✅ 更灵活(允许长度变化) |
存储碎片 | ✅ 不易产生碎片 | ⚠️ 频繁更新变长数据可能产生碎片 |
3. 长度限制
类型 | 最大长度 | 说明 |
---|
CHAR | 255字符(MySQL) | 超过时自动转换为 TEXT 类型 |
VARCHAR | 65,535字节(MySQL,受行大小限制) | UTF8 编码下约 21,844 个汉字 |
4. 适用场景
✅ 优先用 CHAR 的情况
- 存储长度固定的数据(如 MD5 哈希值、邮编、国家代码)
country_code CHAR(2)
- 频繁更新且长度不变的数据(减少碎片)
- 需要精确长度比较的场景(无尾部空格问题)
✅ 优先用 VARCHAR 的情况
- 存储长度变化大的数据(如用户名、地址、描述文本)
username VARCHAR(50)
- 节省存储空间(尤其是大表或长文本)
- 数据尾部空格需保留的场景(CHAR 会自动截断尾部空格)
关键区别总结
对比维度 | CHAR | VARCHAR |
---|
存储机制 | 定长(空格填充) | 变长(仅存有效字符) |
空间效率 | 低(可能浪费空间) | 高(按需分配空间) |
读取性能 | 高(无需计算长度) | 中(需解析长度前缀) |
尾部空格 | 自动移除(检索时丢失) | 保留原样 |
索引效率 | 高(适合固定长度索引) | 中(索引计算稍复杂) |
经典示例分析
存储字符串 "SQL"
(实际长度=3字节)
CREATE TABLE test (
fixed CHAR(10),
dynamic VARCHAR(10)
);
- 存储空间:
CHAR(10)
是 VARCHAR(10)
的 2.5倍 - 存储内容:
CHAR
→ "SQL "
(补7空格)VARCHAR
→ "SQL"
(原样存储)
选择建议
- 固定长度数据 →
CHAR
(如 UUID
、手机号
、枚举代码
) - 长度变化 ≤ 20% →
CHAR
(减少碎片,提升读取速度) - 长度变化大或长文本 →
VARCHAR
(如 文章内容
、用户评论
) - 存储敏感型尾部空格 →
VARCHAR
(CHAR
会丢失原始空格)
💡 终极原则:
- 追求 性能 且 长度固定 →
CHAR
- 追求 空间效率 且 长度不定 →
VARCHAR