nodejs項目mysql使用sequelize支持存儲emoji
本篇主要記錄nodejs項目阿里雲mysql如何支持存儲emoji表情。
因由
最近項目遇到用戶在文本輸入emoji進行存儲的時候導致存儲失敗的問題。經本地調試發現emoji表情在存儲時轉成的四個字節(\xF0\x9F\x90\xAC)導致sequelize報錯,Unhandled rejection SequelizeDatabaseError。由於數據庫使用的是utf8字符集utf8_general_ci,這個校對規則(collation)最大只支持3個字節,所以四個字節的emoji就拋異常了...
擴展
上文提到的utf8_general_ci
與ut8_unicode_ci
是utf8的兩種字符編碼方式,不同之處就是對字符的分類(sorting)和對比(comparison)。
MySQL 5.5.3及以后版本支持使用utf8mb4字符集,它在與utf8數據格式處理性能相同基礎上加強了對字符碼位(code point)的處理能力。與utf8對應的,utf8mb4有utf8mb4_general_ci
和utf8mb4_general_ci
。
- utf8mb4_general_ci 基於Unicode standard sorting與comparison,支持更多的語言種類。
- utf8mb4_general_ci 不能解析所有的Unicode分類規則,在一些特別的語言或字符處理上存在一定的問題。不過在性能上,它能更快的sorting、comparison,因其采用一組性能相關的快捷方式(performance-related shortcuts)。
解決辦法
通過上文我們已經知道一種解決辦法了,但有一個硬性條件就是你的數據庫版本。當你的數據庫版本沒有達到5.5.3怎么辦呢...總結一下,mysql支持存儲emoji表情的方法,至少有兩種。
- 修改數據庫編碼為utf8mb4,前提是你的mysql數據庫版本必須得是5.5.3及以后的。
- 將帶emoji的文本轉為base64來進行存儲,返回時進行相應解碼返回(實誠的方法)。
下面介紹我如何使用第一種方法:
- 將數據庫編碼由utf8改為utf8mb4。
set character_set_client = utf8mb4;
set character_set_connection = utf8mb4;
set character_set_database = utf8mb4;
set character_set_results = utf8mb4;
set character_set_server = utf8mb4;
我們項目用的是阿里的雲數據庫RDS版,可用其提供的線上管理工具DMS進行設置。
- 將已經生成的表也轉成utf8mb4,
alter table TABLE_NAME convert to character set utf8mb4 collate utf8mb4_bin;
- 更新sequelize的配置,主要更改options。關於sequelize相關配置issue可參看
https://github.com/jsha/blocktogether/issues/66 https://github.com/sequelize/sequelize/issues/1220
options: {
dialect: "mysql",
dialectOptions: {
charset: "utf8mb4",
collate: "utf8mb4_unicode_ci",
supportBigNumbers: true,
bigNumberStrings: true
}
}
至此,重啟你的項目,emoji便能夠進行存儲啦~
ps: 內心要強大到混蛋啊喂~
如想了解更多,請移步我的博客。