星期四, 11月 21, 2013

[MySQL] 與unicode的戰爭--MySQL utf8

最近爬了FB的一些資料 遇到一個字串「404325949 ++找好友 󾌸 天天用✌」
發現如果直接用Python寫進MySQL(charset=utf8),會被切斷成「404325949 ++找好友」
後面的字串都不見了,非常疑惑。 
後來發現之前的資料表中有特別設定一個欄位的charset為utf8mb4
問了一下公司前輩也看了一些資料
才發現其中牽扯到unicode和一些MySQL版本支援的問題
這邊講講我的理解



##有關於encoding的故事【這篇】文章講得非常淺顯易懂,強烈推薦給所有為encoding困擾的人

擷取裡面的精華解釋目前遇到的問題:
UTF-8在unicode的表示可以用U+000000到U+10FFFF表示,最多用到6位數
**注意**這裡只是「表示法」,跟實際上紀錄的方式並沒有直接關係,這就是所謂的code point
至於UTF-8,在紀錄上使用1~4個Byte來記錄這些code point所表示的字元們
這裡還有兩個新名詞

  • BMP symbols: 指code point落在U+000000~U+00FFFF的字元們
  • Astral symbols: 指code point落在U+010000~U+10FFFF的字元們
*註: 完整的字元集介紹可以參閱http://en.wikipedia.org/wiki/Plane_(Unicode)

=======回歸正題=======

目前遇到的「󾌸」字元就是code point為U+FE338的字元,在unicode中落在PUA-A這區(真的好狗運)
問題就在於MySQL的utf8 charset只使用1~3個Bytes來記錄字元。
意思是U+0000~U+FFFF這些BPM symbols可以紀錄,但是U+010000~U+10FFFF這些Astral symbol呢?? 很遺憾.....


對照表如下:
Before MySQL 5.5MySQL 5.5 and up
All Unicode 3.0 charactersAll Unicode 5.0 and 6.0 characters
No supplementary charactersWith supplementary characters
ucs2 character set, BMP onlyNo change
utf8 character set for up to three bytes, BMP onlyNo change
New utf8mb4 character set for up to four bytes, BMP or supplemental
New utf16 character set, BMP or supplemental
New utf32 character set, BMP or supplemental

=======結論=======

如果使用MySQL 5.5以上的版本,可以使用utf8mb4等不同的charset來支援

沒有留言: