起源,項目中出現了異常,Message:Incorrect string value: '\xF0\x9F\x87\xB5\xF0\x9F...' for column 'signature' at row 1 經查,前端輸入了emoji的表情——[cano . 40 🇵🇷] 因此了解到需要將數據庫字符集改為 utf8mb4,下面記錄了一步一步解決過程 |
1.了解 utf-8 和 utf-8mb4
utf8是“utf8mb3”的一個別名,可以支持1-3字節表示的unicode字符
utf8mb4的編碼,可以支持1-4字節表示的unicode字符
2. utf-8mb4的作用
為了存儲超出最大長度3字節的任何場景,最常見的就是Emoji 表情(Emoji 是一種特殊的 Unicode 編碼,常見於 ios 和 android 手機上),和一些不常用的漢字,以及任何新增的 Unicode 字符等等
3. 字符集變更風險
`` MySql在5.5.3版本之后增加了一個utf8mb4的編碼,mb4就是most bytes 4的意思,用來兼容四字節的unicode。其實,utf8mb4是utf8的超集,理論上原來使用“utf8”,然后將字符集修改為“utf8mb4”,也並不會對已有的utf8編碼讀取產生任何問題。當然,為了節省空間,一般情況下使用"utf8"也就夠了``
4. 執行變更
4.1 備份數據庫
4.2 判斷當前MySql是否支持utf8mb4,如不支持升級版本到v5.5.3+
select version(); #查看mysql版本 SHOW variables LIKE ‘%char%’; #查看當前字符集 SHOW create database db_name; #查看數據庫字符集 SHOW create table t_name; #查看表字符集
4.3 修改database、table、column字符集 (注意utf8mb4_general_ci和utf8mb4_unicode_ci)
# Update databse
ALTER DATABASE dbgame CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
# Update table
ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
# Update colume (一般修改表就會同步表內列字符集,不過也有遇到過列還仍然是utf8的情況)
ALTER TABLE table_name CHANGE field field VARCHAR(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
!! 如果上述Sql無法修改列則使用以下語句:
# [$Character_Set]為字符集名稱: utf8,[$Collation_Name]為排序規則名稱,即字符序: utf8mb4_unicode_ci
ALTER TABLE [$Table] MODIFY [$Column_Name] [$Field_Type] CHARACTER SET [$Character_Set] COLLATE [$Collation_Name];
4.4 修改mysql配置文件my.cnf(window為my.ini)
如果提示不支持或不識別" Default-character-set = utf8mb4 ",則將 Default 改為小寫 default 即可
# 對本地的mysql客戶端的配置 [client] Default-character-set = utf8mb4 # 對其他遠程連接的mysql客戶端的配置 [mysql] Default-character-set = utf8mb4 # 本地mysql服務的配置 [mysqld] Character-set-lient-andshake = FALSE character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci init_connect = 'SET NAMES utf8mb4' # 忽視連接時指定的字符集 skip-character-set-client-handshake = true
4.5 重啟數據庫,檢查變量
service mysql restart SHOW VARIABLES WHERE variable_name LIKE 'character_set_%' OR variable_name LIKE 'collation%';
注:如果經過上面操作仍無法存儲emoji表情,修改表中字段對應的字符集為utf8mb4。(上面已有提到字段)
#例:修改table_name表中content字段支持emoji表情存取 SELECT * FROM table_name
SHOW FULL COLUMNS FROM table_name
ALTER TABLE table_name CHANGE content content VARCHAR(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
5. 連接字符串
其中的characterEncoding=utf8可以自動被識別為utf8mb4(兼容原來的utf8),而autoReconnection(當數據庫連接異常中斷時,是否自動重新連接?默認為false)強烈建議配上,忽略這個屬性,可能導致緩存緣故 ,沒有讀取到DB最新的配置,導致一直無法試用utf8mb4字符集;
6. Other
提前統計好需要修改的數據庫和表,以及涉及到的具體字段
提前准備好更新時的操作SQL語句,修改庫時快速便捷,不易出錯
如果是阿里雲或騰訊雲等雲RDS,建議先創建一個新的實例,然后把庫表結構轉移過去,測試通過之后,再進行數據恢復和停服遷庫操作。
參考:
Ubuntu下面MySQL的參數文件my.cnf淺析
mysql 修改字符集為utf8mb4
阿里雲 - RDS MySQL字符集相關說明
阿里雲 - RDS MySQL使用utf8mb4字符集存儲emoji表情