Mysql關於處理emoji表情包報錯問題的處理
mysql使用emoji表情的功能,在mysql 5.5 之前,UTF-8編碼只支援1-3個位元組;從MySQL 5.5開始,可以支援4個位元組UTF編碼 utf8mb4 ,一個字元能夠支援更多的字符集,也能夠支援更多表情符號。
utf8mb4相容utf8,且比utf8能表示更多的字元,是utf8字符集的超集。所以現在一些新的業務,比如ISO中的emoji表情,會將MySQL資料庫的字符集設定為utf8mb4。
先看問題:
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。
一:首先我們修改my.cnf引數
1 2 3 4 5 6 7 8 9 10 11 12 13 |
set =utf8mb4
|
二:對資料庫相關的表進行字符集修改
將資料庫轉換為utf8mb4
1 |
|
將已經建好的表也轉換成utf8mb4
1 |
|
將需要使用emoji的欄位設定型別為:
1 |
|
三:重啟資料庫伺服器使之生效
1 2 3 |
|
四:登入資料庫檢查是否如下:
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.35,否則仍然無法使用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中的設定進行使用,這樣就滿足了應用的需求。