阿里雲RDS for MySQL使用utf8mb4編碼儲存Emoji表情

啊哼哼發表於2020-10-15

問題描述

公司的APP專案中輸入Emoji表情和火星文等特殊字元時,後臺介面存入資料庫報錯,錯誤資訊如下:

Caused by: java.sql.SQLException: Incorrect string value: '\xF0\x9F\x98\x97\xF0\x9F...' for column 'CONTENT' at row 1

問題分析

  • 問題是移動端的emoji表情為四個位元組,而MySQL的utf8編碼方式的資料為三個位元組。將MySQL的utf8編碼改為utf8mb4編碼方式就可以進行儲存了。
  • 這裡需要注意是MySQL必須是5.5.3以上版本,我們使用的是5.6版本所以沒有問題可以改。

解決過程

本文主要參考了阿里雲官方幫助文件《RDS MySQL使用utf8mb4字符集儲存emoji表情》

1、檢視資料庫是否支援utf8mb4

在資料庫client終端檢視資料庫是否支援utf8mb4編碼方式

SHOW CHAR SET WHERE Charset LIKE "%utf8%";

在這裡插入圖片描述

2、修改引數

在RDS控制檯-引數配置功能中修改character_set_server引數為utf8mb4。

修改後需要重啟例項方可生效。
在這裡插入圖片描述

3、在RDS中建立新的資料庫

RDS for MySQL資料庫並不支援修改編碼方式,所以要通過新建資料表,然後導資料的方式進行變更。
在這裡插入圖片描述

4、老資料庫資料遷移到新庫

5、改變原資料表的編碼方式

原來已經生成的資料表需要修改編碼方式

-- ex_company 為要修改的表名
ALTER TABLE ex_company CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; 

修改編碼方式的過程中出現了兩個問題

  1. 資料庫報錯“utf8mb4 Specified key was too long; max key length is 767 bytes”。此錯誤的問題在於MySQL資料庫建立索引的欄位不能超過767個位元組,如果建立索引的欄位原來是utf8編碼(3位元組),那麼2553=765可以建立為索引。現在如果改成utf8mb4編碼(4位元組),那麼2554=1020顯然超過767個位元組的規定。可以將建立索引的欄位字元數改少(191正好764)來解決此問題。
alter table ex_order_base modify column sn varchar(191);
  1. 沒有varchar型別欄位的資料表編碼格式不會改。

6、去掉資料庫連結引數中的編碼方式

去掉jdbc連結引數中的“useUnicode=true”和“characterEncoding=UTF-8”引數

修改前:

spring.datasource.url=jdbc:mysql://rdso30006c33s57oufvfo.mysql.rds.aliyuncs.com:3306/pltx-test?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull

修改後:

spring.datasource.url=jdbc:mysql://rdso30006c33s57oufvfo.mysql.rds.aliyuncs.com:3306/pltx-test?zeroDateTimeBehavior=convertToNull

7、將專案jdbc連線指向新的資料庫地址


至此本次變更完成,連結客戶端測試一切正常。

相關文章