一個emoji引發的一條血案:mysql存儲emoji表情字符時報錯解決


以下是我插入一條帶表情的數據到mysql后出現錯誤

2019-03-04 14:24:40,462 ERROR 2807 [-/139.199.27.244/-/2ms POST /api/activityAdd] nodejs.ER_TRUNCATED_WRONG_VALUE_FOR_FIELDError: ER_TRUNCATED_WRONG_VALUE_FOR_FIELD: Incorrect string value: '\xF0\x9F\x98\x82' for column 'content' at row 1

報錯原因:

mysql的utf8編碼的一個字符最多3個字節,但是一個emoji表情為4個字節,所以utf8不支持存儲emoji表情。但是utf8的超集utf8mb4一個字符最多能有4字節,所以能支持emoji表情的存儲

解決辦法:

解決方式有2種:
1、在前端通過js對字符串進行編碼然后再保存到數據庫中,取出來時再對內容進行解碼

2、通過修改數據庫字符編碼utf8mb4

第一種解決方式是使用js提供的方法escape和unescape來對內容進行編解碼,但是問題也很明顯,就是在每個需要顯示和保存的地方我們都需要使用escape和unescape去做處理,這無疑增加了工作量。還有就是我們使用escape編碼之后的內容長度特別長,在數據庫表字段上需要設計很大的長度,對數據庫性能影響也比較大

綜合考慮排除掉這種方式,使用第二種方式去解決

解決過程:

1、linux中修改my.cnf配置文件(默認路徑/etc/my.cnf)

關於my.cnf配置文件參數說明
https://baijiahao.baidu.com/s?id=1608929505838938265&wfr=spider&for=pc

修改之前先查看當前數據庫字符編碼

SHOW VARIABLES WHERE Variable_name LIKE 'character_set_%' OR Variable_name LIKE 'collation%';
character_set_client	utf8mb4
character_set_connection	utf8mb4
character_set_database	utf8
character_set_filesystem	binary
character_set_results	utf8mb4
character_set_server	latin1
character_set_system	utf8
character_sets_dir	/usr/local/mysql/share/charsets/
collation_connection	utf8mb4_general_ci
collation_database	utf8_bin
collation_server	latin1_swedish_ci

可以看到目前我們數據庫編碼使用的是utf8

關於collation_connection 、collation_database 、collation_server關系

系統變量 描述
character_set_client (客戶端來源數據使用的字符集)

character_set_connection (連接層字符集)

character_set_database (當前選中數據庫的默認字符集)

character_set_results (查詢結果字符集)

character_set_server (默認的內部操作字符集)

之后,我們在my.cnf中添加如下配置

[client] 
default-character-set = utf8mb4 
[mysql] 
default-character-set = utf8mb4 

[mysqld] 
character-set-client-handshake = FALSE 
character-set-server = utf8mb4 
collation-server = utf8mb4_unicode_ci 
init_connect='SET NAMES utf8mb4'

然后重啟mysql

service mysqld restart

將數據庫和已經建好的表也轉換成utf8mb4

以上方式更改編碼對於已有的庫和表是不產生影響的,需要我們單獨進行轉換。

更改數據庫編碼:ALTER DATABASE caitu99 CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

更改表編碼:ALTER TABLE TABLE_NAME CONVERT TO CHARACTER SET utf8mb4 COLLATEutf8mb4_general_ci; 
如有必要,還可以更改列的編碼

修改后需要再重啟mysql服務

插入一條表情數據測試

INSERT INTO tb_test (id,name) VALUES (55, x'F09F9A8A');

參考閱讀

https://blog.csdn.net/asahinokawa/article/details/85255732
https://www.cnblogs.com/zhangwufei/p/7017325.html
https://dba.stackexchange.com/questions/89355/unable-to-insert-utf8mb4-characters-in-mysql-5-6
https://blog.csdn.net/eagle89/article/details/82148751
https://www.cnblogs.com/chyingp/p/mysql-character-set-collation.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM