2009年8月14日 星期五

mysql 裡 utf8_general_ci 跟 utf8_unicode_ci 連線校對的差異

mysql 裡 utf8_general_ci 跟 utf8_unicode_ci 連線校對的差異

有用過 mysql 的 UTF-8 編碼的人可能都會對這件事感到疑惑:

連線校對(collation)裡面的

utf8_general_ci

utf8_unicode_ci

到底有什麼差異呢?
在 phpMyAdmin 裡面的說明看起來通通一樣:

utf8_general_ci 統一碼 (Unicode) (多語言), 大小寫不相符
utf8_unicode_ci 統一碼 (Unicode) (多語言), 大小寫不相符

實在是看不出什麼刁來。

所以前一陣子在搞 mysql UTF-8 化的時候,谷歌了一番,
發現這篇文章裡有詳盡的說明:(其實就是把 mysql reference manual 翻譯而已)

utf8_general_ci 在轉換時速度比較快
utf8_unicode_ci 在轉換時比較精準

轉換?怎麼講呢?
簡單說就是當資料要從一個編碼換成另外一個編碼時,
mysql 要在兩個 codepage 裡面找出來相對應的字元位置在哪裡。
對 utf8_general_ci 來說,來源 codepage 裡面的一個字元只能對應到目標 codepage 裡面的一個字元,
而 utf8_unicode_ci 則可以把來源 codepage 裡的一個字元對應到目標 codepage 裡的多個字元(或反過來)。
例如德文裡的 ß 要轉換成英文的時候如果是用 utf8_unicode_ci 轉換會變成正確的 ss ,
但是如果用 utf8_general_ci 的話則會變成單一的 s 而已。

所以如果可以的話請盡量用 utf8_unicode_ci 而不要用 utf8_general_ci ,
雖然對 multibyte 字元來說這兩個都沒差,
但是 utf8 的網頁誰也不知道哪天會不會有這種字元出現在你的網頁上,
所以如果設成 utf8_unicode_ci 你就不需要擔心貼上去之後資料在轉換間遺失了。