公司有新要求,ios客戶端要上線評論中可使用emoji表情的功能,在mysql 5.5 以前,UTF-8編碼只支持1-3個字節;從MySQL 5.5開始,能夠支持4個字節UTF編碼 utf8mb4 ,一個字符可以支持更多的字符集,也可以支持更多表情符號。前端
utf8mb4兼容utf8,且比utf8能表示更多的字符,是utf8字符集的超集。因此如今一些新的業務,好比IOS中的emoji表情,會將MySQL數據庫的字符集設置爲utf8mb4。java
先看問題:mysql
Caused by: java.sql.SQLException: Incorrect string value: '\xF6\x9D\x98\x84' for column 'comment' at row 1 at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1074) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4096) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4028) at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2490) at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2651) at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2734) at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2155) at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2458)
若是咱們將列comment設置爲varchar(100),用於存儲評論信息,如今上線新功能存儲emoji表情,插入emoji表情就會報出上述錯誤,UTF-8編碼有多是兩個、三個、四個字節。Emoji表情是4個字節,而Mysql的utf8編碼最多3個字節,因此數據插不進去。utf8mb4兼容utf8,且比utf8能表示更多的字符。
解決方案:將Mysql的編碼從utf8轉換成utf8mb4。ios
網上的文章各執一詞,本文就生產環境中真實可用的參數進行記錄
sql
總體操做流程其實並不難
數據庫
一:首先咱們修改my.cnf參數bash
[client] default-character-set=utf8mb4 [mysql] default-character-set=utf8mb4 [mysqld] character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci init_connect = 'SET NAMES utf8mb4' character-set-client-handshake = false
二:對數據庫相關的表進行字符集修改服務器
將數據庫轉換爲utf8mb4ide
mysql> ALTER DATABASE erp CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
將已經建好的表也轉換成utf8mb4 編碼
mysql>ALTER TABLE `erp_comment` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
將須要使用emoji的字段設置類型爲:
mysql>ALTER TABLE `erp_comment` MODIFY COLUMN `comment` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
三:重啓數據庫服務器使之生效
[root@HE3 ~]# /etc/init.d/mysqld restart Shutting down MySQL.. SUCCESS! Starting MySQL.... SUCCESS!
四:登陸數據庫檢查是否以下:
mysql> SHOW VARIABLES WHERE Variable_name LIKE 'character%' OR Variable_name LIKE 'collation%'; +--------------------------+--------------------+ | Variable_name | Value | +--------------------------+--------------------+ | character_set_client | utf8mb4 | | character_set_connection | utf8mb4 | | character_set_database | utf8mb4 | | character_set_filesystem | binary | | character_set_results | utf8mb4 | | character_set_server | utf8mb4 | | character_set_system | utf8 | | collation_connection | utf8mb4_unicode_ci | | collation_database | utf8mb4_unicode_ci | | collation_server | utf8mb4_unicode_ci | +--------------------------+--------------------+ rows in set (0.00 sec)
特別說明下:collation_connection/collation_database/collation_server若是是utf8mb4_general_ci,沒有關係。但必須保證character_set_client/character_set_connection/character_set_database/character_set_results/character_set_server爲utf8mb4。
五:讓開發那邊的pom配置中,去掉characterEncoding參數,並從新編譯一下
若是你用的是java服務器,升級或確保你的mysql connector版本高於5.1.13,不然仍然沒法使用utf8mb4
最後再讓前端應用插入emoji表情,就能夠了。
一些小知識點:
其中character-set-server 和 collation-server 這些設置爲utf8mb4字符集是比較容易理解的,就是將MySQL數據庫相關的字符集都設置爲utf8mb4;
但爲了實現客戶端utf8鏈接到MySQL後,使用的也是utf8mb4字符集,就在 mysqld配置中配置了 init_connect='SET NAMES utf8mb4' 表示初始化鏈接都設置爲utf8mb4字符集,再配置一個 skip-character-set-client-handshake = true 忽略客戶端字符集設置,不論客戶端是何種字符集,都按照init_connect中的設置進行使用,這樣就知足了應用的需求。