emoji介紹mysql
Emoji (絵文字,詞義來自日語えもじ,e-moji,moji在日語中的含義是字符)是一套起源於日本的12x12像素表情符號,由慄田穣崇(Shigetaka Kurit)創做,最先在日本網絡及手機用戶中流行,自蘋果公司發佈的iOS 5輸入法中加入了emoji後,這種表情符號開始席捲全球,目前emoji已被大多數現代計算機系統所兼容的Unicode編碼採納,廣泛應用於各類手機短信和社交網絡中。近期,更是有很多網友用emoji圖案玩猜字遊戲,享受這種表情文化帶來的樂趣。web
關於emoji的發音:不少人第一眼見到emoji便會下意識將其誤讀做「一磨嘰」,其實否則,emoji音譯過來大概讀做「誒磨嘰」,當中「e」的發音頗似字母abc的a的發音。sql
最初日本的三大電信運營商各自有不一樣的字符定義,分別是DoCoMo、KDDI和Softbank。隨着iOS內置了Softbank的版本,emoji在全球範圍內風靡(iOS5版本之前)。而Google又本身定義了一套emoji字符。iOS5之後,apple採用了unicode定義的emoji字符(iOS5版本之後)。 數據庫
unicode定義的emoji是四個字符,softbank爲3個字符,emoji的四個字符從存儲到展現對應沒有作過考慮的系統來講,簡直就是災難。windows
面臨問題:網絡
插入Emoji表情,保存到數據庫時報錯:數據結構
SQLException: Incorrect string value: '\xF0\x9F\x98\x84' for column 'review' at row 1
UTF-8編碼有多是兩個、三個、四個字節。Emoji表情是4個字節,而Mysql的utf8編碼最多3個字節,因此數據插不進去。app
解決方案:過濾解決運維
把emoji直接過濾掉,簡單方便有效。雖然損失了幾個emoji字符,但強過不至於致使整條記錄丟失。ide
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