1. 程式人生 > >mysql兼容emoji表情存取

mysql兼容emoji表情存取

蘋果公司 vid 兼容 .com move 上下 計算 .net 服務

emoji介紹

Emoji (絵文字,詞義來自日語えもじ,e-moji,moji在日語中的含義是字符)是一套起源於日本的12x12像素表情符號,由栗田穣崇(Shigetaka Kurit)創作,最早在日本網絡及手機用戶中流行,自蘋果公司發布的iOS 5輸入法中加入了emoji後,這種表情符號開始席卷全球,目前emoji已被大多數現代計算機系統所兼容的Unicode編碼采納,普遍應用於各種手機短信和社交網絡中。近期,更是有不少網友用emoji圖案玩猜字遊戲,享受這種表情文化帶來的樂趣。

關於emoji的發音:很多人第一眼見到emoji便會下意識將其誤讀作“一磨嘰”,其實不然,emoji音譯過來大概讀作“誒磨嘰”,當中“e”的發音頗似字母abc的a的發音。

最初日本的三大電信運營商各自有不同的字符定義,分別是DoCoMo、KDDI和Softbank。隨著iOS內置了Softbank的版本,emoji在全球範圍內風靡(iOS5版本以前)。而Google又自己定義了一套emoji字符。iOS5以後,apple采用了unicode定義的emoji字符(iOS5版本以後)。

unicode定義的emoji是四個字符,softbank為3個字符,emoji的四個字符從存儲到展示對應沒有做過考慮的系統來說,簡直就是災難。

面臨問題:

插入Emoji表情,保存到數據庫時報錯:

SQLException: Incorrect string value: 
\xF0\x9F\x98\x84 for column review at row 1

UTF-8編碼有可能是兩個、三個、四個字節。Emoji表情是4個字節,而Mysql的utf8編碼最多3個字節,所以數據插不進去。


解決方案:過濾解決

把emoji直接過濾掉,簡單方便有效。雖然損失了幾個emoji字符,但強過不至於導致整條記錄丟失。

public static String removeNonBmpUnicode(String str) {  
   if (str == null) {  
       return null;  
   }  
   str = str.replaceAll("
[^\\u0000-\\uFFFF]", ""); return str; }

這種方案能預防能解決問題,並且還能是程序更加健壯,但是從用戶體驗上來說並不好,用戶發的emoji表情丟了,看下面的解決方案。

解決方案:將Mysql的編碼從utf8轉換成utf8mb4。

從 MySQL 5.5.3 開始,MySQL 支持一種 utf8mb4 的字符集,這個字符集能夠支持 4 字節的 UTF8 編碼的字符。 utf8mb4 字符集能夠完美地向下兼容 utf8 字符串。在數據存儲方面,當一個普通中文字符存入數據庫時仍然占用 3 個字節,在存入一個 Unified Emoji 表情的時候,它會自動占用 4 個字節。所以在輸入輸出時都不會存在亂碼的問題了。

要使用 MySQL 的這個特性,首先需要把 MySQL 升級到 5.5.3 以上的版本。

其次,需要修改數據結構中的字符集為 utf8mb4 ,如 utf8mb4_general_ci 。

最後修改數據庫連接字符串默認字符集為utf8mb4。

由於 utf8mb4 是 utf8 的超集,從 utf8 升級到 utf8mb4 不會有任何問題,直接升級即可;如果從別的字符集如 gb2312 或者 gbk 轉化而來,一定要先備份數據庫。

詳細步驟如下:

1修改mysql數據庫字符集(以windows系統為例)

運行services.msc,找到mysql服務,右鍵查看屬性,在可執行文件路徑中找到mysql配置文件位置並打開my.ini配置文件。

技術分享圖片

共有兩處修改

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

[mysqld] --->> character-set-server=utf8mb4

如下圖

技術分享圖片

2修改數據庫連接字符串Charset=utf8mb4

<add name="Default" connectionString="Data Source=****;port=****;Initial Catalog=****;uid=****;password=****;Charset=utf8mb4;Allow User Variables=True" providerName="MySql.Data.MySqlClient" />

3修改完成

這種方式可能帶來的問題:

存儲:在數據表中,對於變長的字段(如VARCHAR2,TEXT),utf8mb4最大可存儲的字符可能少於utf8系列的collation;在索引中,對於文本類型的字段,utf8mb4可索引的字符少於utf8系列的collations。如InnoDB的索引最多使用767字節。如果使用utf8mb4,每一個字符都會預留4字節做索引,而utf8則預留3字節。故此前者是191個字符,後者是255個字符。。

性能:由於以上原因,加上字符集大,utf8mb4的性能可能比utf8系列的collations低,可以參考stackoverfolow上的一個測試結果:http://stackoverflow.com/questions/766809/whats-the-difference-between-utf8-general-ci-and-utf8-unicode-ci,差異不是特別大。

運維:如果一個大的環境內,如果其他的數據庫都是utf8模式,把其中某個庫設置為utf8mb4模式,在後續交接運維可能會造成問題,遺留下坑。

上下遊:數據庫支持unicode的emoji存儲,上下遊不一定支持。比如mysql客戶端驅動(低版本的jdbc就不行)可能不支持utf8mb4,或者DDL的中間件不支持utf8mb4。web端處理utf8mb4字符展示,這些都有可能影響emoji的存儲活著展示。

參考資料:https://blog.csdn.net/ugg/article/details/44225723

mysql兼容emoji表情存取