前端:Java

客户端:IOS

数据库:PerconaServer5.5.20

JDBCURL:jdbc:mysql://192.168.1.1:3306/test?useUnicode=true&characterEncoding=utf8&autoReconnect=true&rewriteBatchedStatements=TRUE

表结构:| groupname    | varchar(32)         | utf8mb4_general_ci

utf8-mb4字符集是MySQL 5.5新增的,我们的业务使用该字符集字段存放图片,比如:手机客户端发出的表情,相比传统字符集和二进制存储方式相比,mb4空间占用小,响应速度快。

手册介绍mb4是定义到列的,可是在实际的应用中是无效的。我们测试了三个场景,分别来验证这个问题。

场景一:character_set_server=utf8 重启mysqld

mysql> show variables like '%character%'; +--------------------------+-------------------------------------------+ | 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                                      | | character_sets_dir       | /data/mysqlPerconasvr5520/share/charsets/ | +--------------------------+-------------------------------------------+8 rows in set (0.00 sec)

 

客户端插入数据,程序报错!

 

查看数据库,数据未插入表中!

根据场景一的问题,我们首先修改了JDBCURL,将characterEncoding=utf8修改为characterEncoding=utf8mb4后又出现了新的问题,MySQL官方驱动目前不支持utf8mb4。

网上有的同学修改了驱动源码, if(str=utf8mb4) str=utf8 ,总的来说也是治标不治本,只是将utf8mb4重定向到utf8上了而已,满足可以在JDBCURL中指定,但实际的字符集还是走的utf8。这不是我们想要的。于是我们修改了MySQL配置。

场景二:character_set_server=utf8mb4 重启mysqld

  1. mysql> show variables like '%character%'

  2. +--------------------------+-------------------------------------------+ 

  3. | Variable_name            | Value                                     | 

  4. +--------------------------+-------------------------------------------+ 

  5. | character_set_client     | utf8                                      | 

  6. | character_set_connection | utf8                                      | 

  7. | character_set_database   | utf8mb4                                   | 

  8. | character_set_filesystem | binary                                    | 

  9. | character_set_results    | utf8                                      | 

  10. | character_set_server     | utf8mb4                                   | 

  11. | character_set_system     | utf8                                      | 

  12. | character_sets_dir       | /data/mysqlPerconasvr5520/share/charsets/ | 

  13. +--------------------------+-------------------------------------------+ 

  14.  

  15. rows in set (0.00 sec)


数据插入成功!

客户端反馈正常!

  

总结:目前MySQL最新的官方驱动是不支持utf8mb4字符集的,所以我们的解决方法就是采用的场景二的配置,给我们DBA带来的问题就是需要将使用到utf8mb4字符集的表迁移到一个新的实例中,因为场景二的配置需要重启mysqld,我们又不希望停止MySQL服务。

友情提示:如果你想在线修改字符集来满足需求,这就是我们的场景三,就不在此展示了,因为从数据库状态看,字符集修改是成功的,插入数据是失败的。


----

正确的做法是:

1.修改表的字符集为utf8mb4;

2.在线set golbal character_set_database=utf8mb4;

3.断开与实例的连接((DBA测试也要断开一次连接,重新登录mysql)

4.jdbc url去掉字符集项,连接到mysql实例后,会使用database的字符集