MySQL5.7版本出现同步或插入中文出现乱码或???显示问题处理
场景
需求是同步一份包含中文等多列数据表到另一个MySQL里面去,同步平台用的是阿里云的maxcomputer,需求比较简单,就是创建一个数据同步任务。
问题描述
首先是maxcomputer,这个版本不会有其他问题,数据平台同步功能是靠数据资源组来同步的,只有数据资源组能够访问到目标的Mysql,我们才能同步过去,所以需要先配置数据源,资源组用的一般用的都是弹性公网IP,为一组,只需要取其中一个IP地址,添加进对方白名单即可。
然后问题就在与mysql5.7对于中文编码的限制问题,当前 MySQL 5.7 实例的字符集相关变量(character_set_client
、character_set_connection
、character_set_database
等)值多为 latin1
,latin1
是单字节编码,不支持中文,这就是插入中文出现 ??
乱码的原因。
我们先把能够编码存储中文的字符编码(Character Set) 和 排序规则(Collation)梳理一下。
一、常见字符编码对比
utf8mb4
(推荐)
- 特点:
- 支持所有 Unicode 字符(包括 emoji、繁体字、罕见符号)。
- 每个字符占用 1-4 字节(如:英文字母占 1 字节,中文占 3 字节,emoji 占 4 字节)。
- 适用场景:存储任意语言的文本,尤其是包含特殊符号或 emoji 的内容。
- 排序规则:常用
utf8mb4_unicode_ci
(不区分大小写)或utf8mb4_bin
(按二进制比较)。
utf8
(不推荐)
- 特点:
- 是
utf8mb4
的子集,仅支持 3 字节 Unicode 字符(基本涵盖常见中文,但不包括所有 emoji 和罕见字符)。 - 每个字符占用 1-3 字节。
- 是
- 风险:存储 4 字节字符(如 🔥、👨👩👧👦)会报错:
Incorrect string value: '\xF0\x9F\x98\x84'
。 - 建议:避免使用,改用
utf8mb4
。
gbk
/gb2312
(旧标准)
- 特点:
- 专门为中文设计,
gbk
支持简体和繁体,gb2312
仅支持简体。 - 每个字符占用 1-2 字节(中文占 2 字节,英文占 1 字节)。
- 专门为中文设计,
- 局限性:
- 不支持 Unicode,无法存储其他语言(如日语、韩语)或特殊符号。
- 逐渐被
utf8mb4
取代。
二、编码与排序规则的关系
- 字符编码:定义如何存储字符(如
utf8mb4
用 4 字节存 emoji)。 - 排序规则:定义如何比较和排序字符(如
_ci
表示不区分大小写)。 - 示例:
utf8mb4_unicode_ci -- utf8mb4 编码,不区分大小写排序
utf8mb4_bin -- utf8mb4 编码,按二进制值排序(区分大小写)
三、MySQL 编码配置
1. 查看当前编码设置
SHOW VARIABLES LIKE 'character_set_%';
SHOW VARIABLES LIKE 'collation_%';
典型输出:
Variable_name | Value |
---|---|
character_set_server | utf8mb4 |
collation_server | utf8mb4_unicode_ci |
2. 修改全局编码(推荐)
编辑 MySQL 配置文件 my.ini
(Windows)或 my.cnf
(Linux):
[client]
default-character-set = utf8mb4[mysql]
default-character-set = utf8mb4[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
重启 MySQL 服务后生效。
3. 创建表时指定编码
CREATE TABLE users (name VARCHAR(50)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
4. 临时修改会话编码
SET NAMES utf8mb4; -- 等价于设置以下三个变量
SET character_set_client = utf8mb4;
SET character_set_results = utf8mb4;
SET character_set_connection = utf8mb4;
四、常见编码问题及解决
1. 插入 emoji 报错
- 错误信息:
Incorrect string value: '\xF0\x9F\x98\x84' for column 'name' at row 1
- 原因:表或字段使用
utf8
编码,无法存储 4 字节字符。 - 解决:
ALTER TABLE users CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
2. 查询结果显示乱码(如 䏿–‡
)
- 原因:客户端、连接、服务器编码不一致。
- 解决:
- 确保
my.ini
配置正确。 - 连接时指定编码(如 JDBC URL 添加
?useUnicode=true&characterEncoding=utf8mb4
)。
- 确保
3. 排序不符合预期(如中文按拼音排序)
- 原因:排序规则选择不当(如
utf8mb4_general_ci
对中文排序不准确)。 - 解决:
ALTER TABLE users MODIFY name VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
最佳实践
- 统一使用
utf8mb4
:所有表、字段、连接均使用utf8mb4
,避免编码不一致导致的问题。 - 配置服务器默认编码:修改
my.ini
,确保新创建的表默认使用utf8mb4
。 - 验证编码设置:
SELECT CHARSET('测试'); -- 应返回 'utf8mb4'
- 避免在 SQL 中手动转换编码:依赖 MySQL 自动转换可能导致意外结果。
通过合理配置编码和排序规则,MySQL 可以完美支持中文及全球各种语言的文本存储与处理。