分享最近在私下玩些小项目时候遇到的乱码问题,以下是环境与配置,若是不完全相同可能情况也会不一样噢(因为我被网上类似情况的杂七杂八解决办法耽误很多时间还无效果)
系统:MacOS Catalina 10.15.2
MySQL版本:5.7.11
Navicat版本:Navicat Premium 12.0.22 (强行免费版)
场景:navicat批量执行sql脚本插入数据,在navicat中查询显示正常,在项目页面(和终端命令行执行查询)显示乱码
首先,我排除了项目jdbc配置以及数据库配置错误,有正常设置连接字符串类型,并且数据库的编码类型为utf8,终端执行下面两个命令结果如下
mysql> show variables like 'character_set%';
+--------------------------+--------------------------------------------------------------------+
| Variable_name | Value |
+--------------------------+--------------------------------------------------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8
mysql> show variables like 'collation_%';
+----------------------+-----------------+
| Variable_name | Value |
+----------------------+-----------------+
| collation_connection | utf8_general_ci |
| collation_database | utf8_general_ci |
| collation_server | utf8_general_ci |
+----------------------+-----------------+
这说明配置一切正常
但是我在navicat中执行show variables like 'character_set%';得到的结果却和终端中不同,其实到这里已经很明显了,navicat的问题,检查数据库连接编码类型为utf8,如果觉得没问题那你就错了,问题就在这里,如果navicat数据库连接设置字符编码类型为utf8的话,插入的中文居然会自动变成latin1类型???我网上搜了“navicat和mysql编码不一致”相关内容看到有人比我先踩了这个坑
而我设置了数据库连接类型为自动之后再SHOW VARIABLES LIKE 'character%';发现我的显示编码类型为utf8mb4???
又借助伟大的Google看到一个觉得比较正确的解释:
MySQL从版本4.1开始支持UTF-8 。那是2003年 - 在今天的UTF-8标准发布之前,RFC 3629。
以前的UTF-8标准RFC 2279每个字符最多支持6个字节。MySQL开发人员在2002年3月28日的MySQL 4.1的第一个预发行版本中编写了RFC 2279 ,然后在9月对MySQL的源代码进行了一次神秘的,一字节的调整:“UTF8现在只能处理3个字节的序列。”但事实上真正的UTF8编码每个字符最多需要4个字节,这是一次尴尬的代码提交(据说是试图优化速度和空间,然而并没有😂)
utf8能够存下大部分中文汉字,但如果遇到 4 字节的宽字符(中文生僻字或者emoji表情等)就会插入异常,于是MySQL在5.5.3之后增加了这个utf8mb4的编码,mb4就是most bytes 4的意思,专门用来兼容四字节的unicode。好在utf8mb4是utf8的超集,除了将编码改为utf8mb4外不需要做其他转换。当然,为了节省空间,一般情况下使用utf8也就够了。可以简单的理解 utf8mb4 是目前最大的一个字符编码,支持任意文字
如果担心用utf8会出问题,这里看到有解决办法
参考:https://medium.com/@adamhooper/in-mysql-never-use-utf8-use-utf8mb4-11761243e434