mysql里一个中文汉字占多少字节数?

来源:编程网作者:日本程序员头衔:程序员
导读:本期聚焦于日本程序员创作的《mysql里一个中文汉字占多少字节数?》,敬请观看详情。很多开发者在使用mysql存储中文数据时,都会疑惑一个中文汉字到底占多少字节数。这个问题的答案并不是固定的,和mysql使用的字符集、字符集对应的编码规则有直接关系。不同的字符集配置下,中文汉字占用的字节数会有明显差异,比如常见的utf8和utf8mb4字符集的存储规则就不同。了解这些差异能帮助开发者更合理地设计数据库表结构,避免出现字段长度不足或者存储空间浪费的问题,也能在排查数据存储异常时快速定位原因。

mysql里一个中文汉字占多少字节数?

MySQL中一个中文汉字到底占多少字节?一文讲透字符集与存储空间

引言:为什么需要关心中文占用的字节数?

在日常开发中,我们经常需要在数据库中存储中文数据,比如用户昵称、文章标题、商品名称等。然而,很多开发者会发现一个奇怪的现象:明明定义了VARCHAR(255),却存不下255个中文汉字;或者在某些情况下,同样的字段在另一台服务器上却能存更多。这背后的根本原因,就在于MySQL所使用的字符集不同。

字符集决定了字符与字节之间的映射规则。不同的字符集对同一个汉字的编码长度可能完全不同。理解这一点,不仅有助于合理设计数据库表结构,避免存储空间浪费或数据截断,还能在迁移数据、跨系统交互时避免乱码问题。本文将从常用字符集入手,详细讲解中文在MySQL中的字节占用情况,并提供验证方法和实战建议。

不同字符集下中文汉字的字节占用情况

MySQL支持多种字符集,其中常用于存储中文的主要有GBK、GB2312、UTF8和UTF8MB4。它们的编码规则各不相同,导致同一个汉字占用的字节数也不同。

GBK字符集:每个中文固定2字节

GBK是国家标准GB 2312的扩展字符集,向下兼容GB 2312。它采用双字节编码,即任何一个中文字符(包括简体中文和繁体中文)都固定占用2个字节。这意味着如果你使用GBK字符集,一个VARCHAR(100)的字段理论上最多可以存储100个汉字。

GBK的优势在于节省空间,尤其适合历史遗留系统或对存储空间敏感的场景。但它的缺点也很明显:不支持国际通用字符,比如emoji表情、生僻字(如“𪚥”)就无法存储。此外,在与现代Web应用交互时,如果前后端使用UTF-8编码,频繁的转码可能导致性能损耗和乱码风险。

GB2312字符集:早期的中文标准,也是2字节

GB2312是中国国家标准总局于1980年发布的中文编码标准,收录了6763个汉字和682个其他符号。它同样采用双字节编码,每个汉字固定占用2个字节。不过GB2312覆盖的汉字数量有限,许多生僻字、繁体字都不在其中。如今新开发的系统很少单独使用GB2312,通常被GBK或UTF8MB4取代。

UTF8字符集:MySQL中的“阉割版”,中文占3字节

很多人以为UTF-8就是万能的Unicode实现,但在MySQL中,“utf8”字符集并不是真正的完整UTF-8。MySQL的utf8最多只支持3个字节的字符,这意味着它只能编码Unicode基本多文种平面(BMP)中的字符。而绝大多数常用汉字(如“中”、“国”、“人”)正好落在这个范围内,因此每个汉字占用3个字节。

为什么MySQL的utf8是“阉割版”?这是因为早期MySQL设计时,UTF-8标准尚未完全普及,为了性能和兼容性,选择了只支持3字节的方案。后来随着emoji和生僻字的需求增加,MySQL才推出了真正的完整UTF-8实现——utf8mb4。因此,如果你的数据库使用utf8字符集,一个VARCHAR(255)字段最多只能存储85个汉字(255 ÷ 3 ≈ 85),而且无法存储emoji表情。

UTF8MB4字符集:真正的完整UTF-8,中文占3或4字节

utf8mb4是MySQL从5.5.3版本开始引入的字符集,它是“utf8 most bytes 4”的缩写,最多支持4个字节的字符。它完全兼容UTF-8标准,可以编码所有Unicode字符,包括emoji、生僻汉字(如“𪚥”、“𠀀”等)。

对于绝大多数常用汉字(如“你好”),utf8mb4依然使用3个字节编码。但对于那些超出BMP范围的生僻字,则需要4个字节。例如“𪚥”(四个“龙”字叠在一起,读作zhé)就是一个典型的4字节汉字。因此,在utf8mb4字符集下,一个VARCHAR(255)字段能存储的汉字数量是不确定的:如果全是常用字,可以存85个;如果包含生僻字,最多只能存63个(255 ÷ 4 ≈ 63)。实际应用中,建议按最坏情况(4字节)来估算容量。

字符集

中文汉字占用字节数

说明

GBK

2字节

固定双字节,兼容GB2312,不支持emoji

GB2312

2字节

早期标准,汉字数量有限

utf8

3字节

MySQL特有,不支持4字节字符

utf8mb4

3或4字节

完整UTF-8,常用字3字节,生僻字4字节

如何查看当前字段的字符集

在实际开发中,我们需要知道表或字段究竟使用了哪种字符集。MySQL提供了多种方式来查看。

使用SHOW FULL COLUMNS命令

最直接的方法是查询表的字段信息。假设我们有一张名为users的表,执行以下SQL:

SHOW FULL COLUMNS FROM users;

结果中的Collation列会显示每个字段的排序规则。排序规则的命名规则是“字符集语言类型”,例如utf8mb4_general_ci表示该字段使用utf8mb4字符集,gbk_chinese_ci表示使用gbk字符集。通过排序规则的前缀,我们就能反推出字符集。

查看表和数据库的默认字符集

如果想查看整个表的默认字符集,可以使用:

SHOW CREATE TABLE users;

在输出中会看到DEFAULT CHARSET=utf8mb4这样的信息。同样,查看数据库的默认字符集:

SHOW CREATE DATABASE mydb;

了解这些信息,可以帮助我们在设计阶段就统一字符集,避免表与数据库、字段与表之间的字符集冲突。

验证中文占用字节数的方法

理论说再多,不如亲手测一测。MySQL提供了两个非常有用的函数:LENGTH()CHAR_LENGTH()

  • LENGTH(str):返回字符串所占用的字节数。
  • CHAR_LENGTH(str):返回字符串的字符个数(不管每个字符占几个字节)。

通过对比这两个函数的返回值,就能算出每个字符的平均字节数。

测试普通中文

首先,确保当前连接的字符集与你想要测试的一致。使用SET NAMES语句设置会话级字符集:

SET NAMES utf8mb4;
SELECT LENGTH('中') AS byte_length, CHAR_LENGTH('中') AS char_length;

执行结果:byte_length为3,char_length为1。说明在utf8mb4下,普通汉字“中”占用3个字节。

测试生僻中文

换一个生僻字,比如“𪚥”:

SET NAMES utf8mb4;
SELECT LENGTH('𪚥') AS byte_length, CHAR_LENGTH('𪚥') AS char_length;

结果:byte_length为4,char_length为1。证实了生僻字在utf8mb4下占用4个字节。

测试GBK字符集

如果我们改用GBK字符集:

SET NAMES gbk;
SELECT LENGTH('中') AS byte_length, CHAR_LENGTH('中') AS char_length;

结果:byte_length为2,char_length为1。注意,如果尝试在GBK下插入“𪚥”,会因为无法编码而报错。

测试混合字符串

还可以测试包含英文、数字和中文的混合字符串:

SET NAMES utf8mb4;
SELECT LENGTH('Hello世界') AS byte_length, CHAR_LENGTH('Hello世界') AS char_length;

结果:byte_length= 5(英文字母各1字节)+ 6(两个汉字各3字节)= 11;char_length= 7(5个字母+2个汉字)。这个例子很直观地展示了不同字符的字节差异。

实际开发中的注意事项

合理设置字段长度

在设计VARCHAR字段时,不能只看字符数上限,还要考虑字符集带来的字节限制。MySQL中VARCHAR(N)的N指的是字符数,而不是字节数。但实际存储时,总字节数不能超过65535(行大小限制,且受编码影响)。更重要的是,索引也有长度限制(通常为767字节或3072字节,取决于innodb_large_prefix设置)。

  • 如果使用GBK,VARCHAR(255)最多可存255个汉字,字节数为510,远小于65535。
  • 如果使用utf8,VARCHAR(255)最多可存85个汉字,字节数为765,接近索引限制。
  • 如果使用utf8mb4,VARCHAR(255)最多可存63个汉字(按4字节算),字节数为1020,超过了默认的索引前缀767字节,可能导致无法创建索引或需要调整参数。

因此,在创建表时,建议根据实际需求选择合适的字符集。如果不需要存储emoji和生僻字,使用utf8或GBK可以节省空间并提高索引效率。如果需要全面支持Unicode,则应使用utf8mb4,并将VARCHAR长度控制在合理范围内(例如不超过191,因为191×4=764,刚好小于767)。

显式指定字符集,避免继承混乱

MySQL中字符集的继承顺序是:服务器级别 → 数据库级别 → 表级别 → 字段级别。如果在建表时不指定字符集,它会继承数据库的默认字符集;而数据库的默认字符集又可能继承自服务器的配置。这种隐式继承很容易导致不同环境下的行为不一致。

例如,你在本地开发时数据库默认是utf8,但线上服务器默认是utf8mb4,那么同样的建表语句会产生不同的结果。为了避免这种隐患,建议在建表和建字段时显式指定字符集:

CREATE TABLE articles (
    id INT PRIMARY KEY AUTO_INCREMENT,
    title VARCHAR(100) CHARACTER SET utf8mb4 NOT NULL,
    content TEXT CHARACTER SET utf8mb4
) DEFAULT CHARSET=utf8mb4;

这样无论服务器默认配置如何,你的表始终使用预期的字符集。

注意连接字符集与存储字符集的匹配

除了存储时的字符集,客户端与MySQL之间的连接字符集也至关重要。如果客户端发送的数据是UTF-8编码,但连接的character_set_client设置为GBK,MySQL就会错误地解析数据,导致乱码。通常建议在应用程序中统一使用UTF-8(utf8mb4),并在建立连接后执行SET NAMES utf8mb4,确保传输和存储的一致性。

迁移数据时的字符集转换

当需要将旧系统的GBK数据迁移到新系统的utf8mb4时,不能简单地复制数据,而要进行字符集转换。MySQL提供了ALTER TABLE ... CONVERT TO CHARACTER SET语句,但要注意这可能会改变数据的实际编码,最好先在测试环境验证。更稳妥的做法是导出数据时指定字符集,导入时再指定目标字符集。

总结

MySQL中一个中文汉字占用的字节数,完全由字符集决定。GBK和GB2312固定2字节,utf8固定3字节,utf8mb4则视字符而定(常用字3字节,生僻字4字节)。理解这一点,对于数据库设计、容量规划、索引优化以及避免乱码都有重要意义。

在实际开发中,建议优先选择utf8mb4字符集,因为它能完美支持所有Unicode字符,包括emoji和生僻字。同时,要显式指定字符集,合理设置字段长度,并确保连接字符集与存储字符集一致。通过这些措施,你的数据库就能稳定、高效地承载各种语言文字,从容应对全球化应用的挑战。

mysql中文汉字字节数字符集utf8mb4修改时间:2026-08-23 06:16:44

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。