当前位置: 代码网 > it编程>数据库>Mysql > mysql中 char 和 varchar 的区别解析

mysql中 char 和 varchar 的区别解析

2025年11月25日 Mysql 我要评论
这是一个在 mysql 面试和日常开发中非常经典的问题。char和varchar是两种最常用的字符串数据类型,它们的核心区别在于存储和检索的方式。下面我将从多个维度详细解释它们的区别,并给出选择建议。

这是一个在 mysql 面试和日常开发中非常经典的问题。char 和 varchar 是两种最常用的字符串数据类型,它们的核心区别在于存储和检索的方式

下面我将从多个维度详细解释它们的区别,并给出选择建议。

核心区别总结

特性charvarchar
长度处理固定长度可变长度
存储方式分配定义的全部空间,不足部分用空格填充只存储实际字符数(+1或+2字节存储长度信息)
存储空间固定,为声明的长度可变,为实际字符串长度 + 长度前缀
尾部空格检索时会自动删除检索时会保留
读取速度较快(固定长度,无需计算)稍慢(需要根据长度信息读取)
适用场景长度固定或近乎固定的数据(如md5、uuid、状态码)长度变化较大的数据(如姓名、地址、描述)

详细解释

1. 存储方式与空间占用

  • char(n)
    • 你声明一个 char(10) 的列,无论你存入 "hi"(2字符)还是 "hello"(5字符),mysql 都会在磁盘上分配并占用 10 个字符的空间
    • 如果存入的字符串长度不足,mysql 会在其右侧用空格填充到指定长度。
    • 例如,存储 "a" 到 char(4) 列,实际存储的是 "a   "
  • varchar(n)
    • 你声明一个 varchar(10) 的列,存入 "hi" 大约占用 3 个字节(2个字符 + 1字节的长度前缀),存入 "hello" 大约占用 6 个字节(5个字符 + 1字节的长度前缀)。
    • varchar 需要使用额外的 1 或 2 个字节来存储“字符串的长度”这个信息
      • 如果声明的最大长度 n <= 255,则使用 1 个字节 作为长度前缀。
      • 如果声明的最大长度 n > 255,则使用 2 个字节 作为长度前缀。
  • 它只存储实际的字符串内容,不会用空格填充。

2. 尾部空格的处理(关键行为差异)

这是另一个非常重要的区别,尤其是在进行字符串比较时。

char:在检索(select)时会自动移除存储时填充的尾部空格。

-- 假设有一个 char(5) 的列
insert into table (char_column) values ('abc '); -- 存储为 'abc  '
select char_column, length(char_column) from table; 
-- 检索结果:'abc',长度为 3(尾部空格被移除)

varchar:在检索时会保留尾部空格。

-- 假设有一个 varchar(5) 的列
insert into table (varchar_column) values ('abc  '); -- 存储 'abc  ' 及其长度信息
select varchar_column, length(varchar_column) from table;
-- 检索结果:'abc  ',长度为 5(尾部空格被保留)

注意:由于 char 的这种行为,当使用 = 比较时:

'abc '(char)和 'abc'(char)是相等的;

'abc '(char)和 'abc'(varchar)是相等的;

'abc '(varchar)和 'abc'(varchar)是不相等的。

3. 性能考量

  • char
    • 优点:由于长度固定,在磁盘上的记录也是定长的,所以读写速度通常更快。mysql 可以很容易地计算出第 n 条记录的位置,尤其是在 myisam 这种存储引擎中,对于全表扫描或频繁更新的场景有优势。
    • 缺点:可能会浪费存储空间,尤其是当存储的数据长度远小于定义长度时。
  • varchar
    • 优点节省存储空间
    • 缺点:由于记录长度可变,更新数据可能会导致行的大小发生变化,从而可能引发页分裂(对于 innodb),影响一点性能。此外,读取时需要先读取长度信息,再读取具体数据,过程稍复杂。

如何选择?

请根据你的业务场景来决定:

  • 使用 char 的情况:
    • 存储的字符串长度非常固定或变化极小。
  • 经典例子:
    • md5/sha1 哈希值(长度固定,如 md5 总是 32字符)
    • uuid(虽然可以用 char(36),但现在更推荐存储为二进制或使用 uuid_short()
    • 国家代码(如 char(2) 用于 'us', 'cn')
    • 定长的状态码或标志位(如 char(1) 用于 'y'/‘n’)
  • 避免使用char的情况:
    • 需要精确保留字符串的原始格式(包括尾部空格)
  • 使用 varchar 的情况:
    • 存储的字符串长度变化很大

一个简单的例子

create table test_string (
    id int primary key,
    fixed_char char(5),
    variable_varchar varchar(5)
);
insert into test_string (id, fixed_char, variable_varchar) values
(1, 'a', 'a'),       -- char存储 'a    ', varchar存储 'a'
(2, 'abcde', 'abcde'); -- 两者都存满
-- 查询并显示长度
select 
    fixed_char, 
    length(fixed_char) as char_length,
    variable_varchar, 
    length(variable_varchar) as varchar_length
from test_string;

结果可能如下

fixed_charchar_lengthvariable_varcharvarchar_length
a1a1
abcde5abcde5

总结

  • 追求空间效率,数据长度多变 -> 选择 varchar。这是绝大多数场景下的选择。
  • 追求极致性能,数据长度固定 -> 选择 char
  • 深刻理解 char 会剔除检索结果的尾部空格 这一点,可以避免很多意想不到的查询 bug。

在现代 mysql 版本和 innodb 存储引擎下,对于大多数通用场景,varchar 因其灵活性而更受欢迎。除非你非常确定某个字段的长度是绝对固定的,否则从 varchar 开始通常是一个安全的选择。

到此这篇关于mysql中 char 和 varchar 的区别的文章就介绍到这了,更多相关mysql char 和 varchar区别内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com