nodejs項目mysql使用sequelize支持存儲emoji


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_ciut8_unicode_ci是utf8的兩種字符編碼方式,不同之處就是對字符的分類(sorting)和對比(comparison)。

MySQL 5.5.3及以后版本支持使用utf8mb4字符集,它在與utf8數據格式處理性能相同基礎上加強了對字符碼位(code point)的處理能力。與utf8對應的,utf8mb4有utf8mb4_general_ciutf8mb4_general_ci

  • utf8mb4_general_ci 基於Unicode standard sorting與comparison,支持更多的語言種類。
  • utf8mb4_general_ci 不能解析所有的Unicode分類規則,在一些特別的語言或字符處理上存在一定的問題。不過在性能上,它能更快的sorting、comparison,因其采用一組性能相關的快捷方式(performance-related shortcuts)。

解決辦法

通過上文我們已經知道一種解決辦法了,但有一個硬性條件就是你的數據庫版本。當你的數據庫版本沒有達到5.5.3怎么辦呢...總結一下,mysql支持存儲emoji表情的方法,至少有兩種。

  1. 修改數據庫編碼為utf8mb4,前提是你的mysql數據庫版本必須得是5.5.3及以后的。
  2. 將帶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: 內心要強大到混蛋啊喂~

 

如想了解更多,請移步我的博客


免責聲明!

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



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