MySQL的字符集比其他关系型数据库(如Oracle、SQL Server)更为复杂。在MySQL环境初期搭建时,未明确字符集和校对规则,后期会碰到一系列字符编码相关的问题。比如:
乱码;
数据截断;
排序异常;
多表Join,字符集不一致隐式转换导致索引失效;
字符集导致前后空格去掉,判断逻辑错误;
无法保存4字数据;
到最后就需要大动手术,进行标准化,之后再进行数据的统一迁移。
跟其他关系型数据库对比,MySQL的字符集设置 多层级(库,表,列,连接)设置,区分大小写,存在utf8的超级utf8mb4,对于前后空格有自身的理机制。但一些个别问题,可以通过一些小技巧,解决字符集不一致的问题。本次介绍一些字符集处理技巧。
1.字符集转化
#将字符串从 latin1 转换为 utf8mb4
mysql> SELECT CONVERT('Hello' USING utf8mb4);
2.排序规则转化
COLLATE 用于指定字符串的排序规则(如大小写敏感、多语言排序等),影响 WHERE、ORDER BY、GROUP BY 等操作的比较行为。
#强制字段使用特定排序规则进行比较
mysql> SELECT * FROM users
WHERE name COLLATE utf8mb4_unicode_ci = '张三';
#返回结果按指定排序规则排序
mysql> SELECT name FROM users
ORDER BY name COLLATE utf8mb4_unicode_ci;
#8.0默认是0900字符集
mysql> select COLLATION('abc'),COLLATION(CONVERT('abc' USING utf8mb4));
+------------------+-----------------------------------------+
| COLLATION('abc') | COLLATION(CONVERT('abc' USING utf8mb4)) |
+------------------+-----------------------------------------+
| utf8mb4_bin | utf8mb4_0900_ai_ci |
+------------------+-----------------------------------------+
3.乱码
-- 错误示例:字段是 utf8mb4,但客户端用 latin1 解码
mysql> SELECT * FROM users WHERE text = '中文'; -- 乱码或无结果
#设置连接字符集
mysql> SET NAMES utf8mb4;
mysql> SELECT * FROM table WHERE text COLLATE utf8mb4_unicode_ci = '中文';
#直接在连接字符串中指定
jdbc:mysql://localhost:3306/db?useUnicode=true&characterEncoding=utf8mb4
4.强制大小写不敏感查询
#默认情况下,utf8mb4_general_ci 是大小写不敏感的
mysql> SELECT * FROM users WHERE name = 'John' COLLATE utf8mb4_general_ci;
#显式指定大小写不敏感
mysql> SELECT * FROM users WHERE name COLLATE utf8mb4_unicode_ci = 'john';
5.修改查询结果的排序规则
#返回结果按指定排序规则排序
mysql> SELECT name FROM users
ORDER BY name COLLATE utf8mb4_unicode_ci;
6.处理空格
#保留末尾空格比较
mysql> SELECT * FROM users WHERE name = 'value ' COLLATE utf8mb4_bin;
#显式去除空格
mysql> SELECT * FROM users WHERE TRIM(name ) = TRIM('value');
7.避免数据截断的技巧
#使用严格模式防止静默截断
mysql> SET @@sql_mode = 'STRICT_TRANS_TABLES';
8.特殊字符处理
-- 转义特殊字符
mysql> SET @str = '特殊"字符☺\'串';
mysql> SELECT QUOTE(@str); -- 输出带引号和转义的字符串
+-------------------------+
| QUOTE(@str) |
+-------------------------+
| '特殊"字符☺\'串' |
+-------------------------+
1 row in set (0.00 sec)
9.导入导出处理技巧
#导出时指定字符集
mysqldump -u root -p --default-character-set=utf8mb4 dbname > dump.sql
#导入时转换字符集
mysql -u root -p --default-character-set=utf8mb4 dbname < dump.sql
#LOAD DATA时指定字符集
LOAD DATA INFILE 'data.txt' INTO TABLE tablename
CHARACTER SET utf8mb4
FIELDS TERMINATED BY ',';
备注:dump.sql内部如有指定字符集,default就会失效。