convert() 主要用于字符集转换(如 convert(expr using charset)),不校验解码合法性;cast() 是标准sql类型转换(如 cast(expr as type)),仅改变数据类型而不处理字符集。

mysql 中 CONVERT() 和 CAST() 的实际区别
二者都能做类型转换,但行为和适用场景不同。用错会导致隐式截断、乱码或报错。
-
CONVERT(expr USING charset)主要用于字符集转换,比如把latin1字节流按utf8mb4重新解释;它不校验内容是否真能解码,强行转可能出 -
CAST(expr AS type)是标准 SQL 类型转换,如CAST('123' AS SIGNED),不处理字符集,只改数据类型 - 混合使用时顺序很重要:先
CAST再CONVERT,否则可能在错误的字符集下解析字节
查看和修正表字段的实际字符集与排序规则
很多乱码问题不是导入导致的,而是字段定义本身没对齐。不能只看数据库或连接层的 character_set 设置。
- 查字段级字符集:
select COLUMN_NAME, CHARACTER_SET_NAME, COLLATION_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'your_db' AND TABLE_NAME = 'your_table'; - 改单个字段(保留数据):
ALTER TABLE your_table MODIFY COLUMN your_column VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - 注意:
MODIFY会重建列,大表慎用;CHANGE语法类似但需重复写列名
连接层字符集不一致引发的“存得进、查不出”问题
客户端声明的字符集和服务器实际处理的不一致,会导致 INSERT 看似成功,SELECT 却返回乱码或空值。
- 确认当前连接的字符集:
SHOW VARIABLES LIKE 'character_set%';关键看
character_set_client、character_set_connection、character_set_results是否全为utf8mb4 - 临时修复连接:
SET NAMES utf8mb4;等价于同时设上述三个变量
- 永久生效需在
my.cnf的[client]和[mysqld]段都加上default-character-set = utf8mb4(MySQL 8.0+ 推荐用character-set-server)
从 latin1 表导出再导入 utf8mb4 时的典型翻车点
直接 mysqldump --default-character-set=latin1 导出,再用 utf8mb4 连接导入,大概率出现双编码乱码(例如 “林天”)。
- 真正安全的做法是:导出时用
--skip-set-charset+ 手动指定--default-character-set=binary,让 mysqldump 把字段当二进制处理 - 导入前确保目标库/表已设为
utf8mb4,然后用SET NAMES binary;开头,再执行 SQL - 验证方法:查一个中文字段的
HEX()值,utf8mb4下应为 3~4 字节一组,如 “中” 是E4B8AD;若看到C3A6C2BEB3C2A4就是被二次编码了
字符集问题从来不是单点配置能解决的,客户端、连接、表定义、字段定义、存储引擎(如 InnoDB 对 utf8mb4 索引长度有限制)必须全部对齐,漏掉任意一环,数据就可能悄悄损坏。