Emoji 本質與 Mysql 處理方式

<h3>先補習一下Unicode 與 UTF-8的歷史演變過程</h3>
http://www.lxweimin.com/p/ab0dcfb9bb74

以下內容轉自文章:
http://blog.csdn.net/ugg/article/details/44225723

http://blog.csdn.net/tge7618291/article/details/7599902

emoji資料

今天研究了emoji,挺有意思,資料挺多,摘要一些信息給大家分享,也算是自己記錄學習。

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字符,但強過不至于導致整條記錄丟失。

[php] view plain copy 在CODE上查看代碼片派生到我的代碼片
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 是 utf8 的超集,從 utf8 升級到 utf8mb4 不會有任何問題,直接升級即可;如果從別的字符集如 gb2312 或者 gbk 轉化而來,一定要先備份數據庫。

然后,修改 MySQL 的配置文件 /etc/my.cnf,修改連接默認字符集為 utf8mb4 ,如果是自己寫的 PHP 腳本,也可以在連接數據庫以后首先執行一句 SQL: SET NAMES utf8mb4;。這時候,PHP 應該就可以正常保存 Emoji 到數據庫了。

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

存儲:在數據表中,對于變長的字段(如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的存儲活著展示。

從上面的信息,從數據庫層面如果不是特別看重存儲,性能,運維并能解決上下游的問題,數據庫是完全可以支持emoji的,但是有個新問題沒有解決,emoji在iOS上展示OK,andriod設備如何展示emoji表情?

解決方案:轉義解決

1:unicode emoji轉softbank的emoji。

我們知道unicode emoji是4個字節,softbank定義的emoji占用3個字節存儲,通過emoji for php http://code.iamcal.com/php/emoji/,我們可以把unicode的emoji方式轉換為softbank方式,從而實現不修改數據庫,就能存儲emoji,相對于數據庫層面的解決問題的方式,動作要小的多,并且也不會有性能,運維等方面的問題。但是有個不可避免的問題是,Softbank方式已經不再維護,所以新增加的emoji表情,Softbank中都沒有,會造成部分emoji表情丟失的情況。

2:ubb

UBB代碼是HTML(標準通用標記語言下的一個應用)的一個變種,是Ultimate Bulletin Board (國外的一個BBS程序)采用的一種特殊的TAG。您也許已經對它很熟悉了。UBB代碼很簡單,功能很少,但是由于其Tag語法檢查實現非常容易,所以不少網站引入了這種代碼,以方便網友使用顯示圖片/鏈接/加粗字體等常見功能。

比如emoji的太陽符號,他的unicode emoji編碼為U+2600,在存入數據庫時,可以把它轉換成 UBB 代碼 [emoji]2600[/emoji] 保存,讀取的時候,可以轉換回來。當然針對不同的設備,比如andriod我們可以轉義成andriod可以處理的emoji符號。

這種轉移,可以很好解決iOS和Andriod顯示emoji的問題,但是還存在幾個問題。

1:andriod和iOS的emoji并不相同,相同的編碼 可能在iOS上是太陽,而在andriod上是陰天,解決這種問題方式最好做下iOS和andriod下的emoji映射,同時可以在web上通過js轉義處理。

2:性能,采用轉義的方式處理,性能肯定會有所下降,但是可以容忍。

與UBB對應的是html轉義,這種方式,其實和ubb有些類似, 使用 HTML轉義字符 ?,結果和性能和UBB差不多,從規范化上來說,ubb方式更好一些。

參考資料

PHP-emoji轉換表:http://code.iamcal.com/php/emoji/
unicode Emoji Symbols: http://www.unicode.org/~scherer/emoji4unicode/20091221/utc.html
emoji圖標和unicode對應關系:http://www.easyapns.com/iphone-emoji-alerts
談談Unicode編碼,簡要解釋UCS、UTF、BMP、BOM等名詞:http://www.fmddlmyy.cn/text6.html
emoji在線轉換工具:http://unicodey.com/js-emoji/demo.htm
Emoji表情圖標在iOS與PHP之間通信及MySQL存儲:http://blog.csdn.NET/wildfireli/article/details/9370161
Mysql中校對集utf8_unicode_ci與utf8_general_ci的區別:http://hi.baidu.com/phpkoo/item/38238bd8505899e955347fcahttp://stackoverflow.com/questions/766809/whats-the-difference-between-utf8-general-ci-and-utf8-unicode-ci
Mysql排序規則utf8_unicode_ci與utf8_general_ci的區別:http://justdo2008.iteye.com/blog/2162842
Unicode Character Sets:http://dev.mysql.com/doc/refman/5.0/en/charset-unicode-sets.html
MySQL設置utf8mb4編碼:http://www.linuxidc.com/Linux/2014-07/104231.htm|
andriod支持emoji解決方案:http://blog.csdn.net/waylife/article/details/11095113
Supporting New Emojis on iOS 6:http://blog.manbolo.com/2012/10/29/supporting-new-emojis-on-ios-6
讓MySql支持Emoji表情(MySQL中4字節utf8字符保存方法):http://www.w2bc.com/Article/8533
如何處理emoji等4字節的Unicode字符:http://zhidao.baidu.com/link?url=z6PW1ya6plRBgFN7M2zdVLXUnmxYcH2_VYK8nW9Yi9-kh2estgmJomw1LssmsA853WYHsRtulkJn2okq0a3TAUDQHIiMe7b0VS-FeGMNYUu
suppoting new emoji for ios6:http://blog.manbolo.com/2012/10/29/supporting-new-emojis-on-ios-6
UTF-8格式emoji:http://punchdrunker.github.io/iOSEmoji/table_html/ios6/index.html

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,333評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,491評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,263評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,946評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,708評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,186評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,255評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,409評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,939評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,774評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,976評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,518評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,209評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,641評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,872評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,650評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,958評論 2 373

推薦閱讀更多精彩內容