2012-09-14 101 views
2

我在MySQL以下查詢:MySQL WHERE`character` ='a'匹配a,A,Ã等。爲什麼?

SELECT id FROM unicode WHERE `character` = 'a' 

unicode包含每個Unicode字符的ID(它的整數編碼值)沿。由於表的排序規則設置爲utf8_unicode_ci,因此我預計上述查詢只返回97(字母'a')。相反,它返回一個包含了許多「A'封樣的ID 119行:

A A A ...

這似乎是忽略大小寫和字符的多字節性質。

任何想法?

+0

出於好奇,你不能使用['ORD()'](http://dev.mysql.com/doc/en/string-functions.html#function_ord)而不是維護這張表嗎?例如,'SELECT ORD('a');' – eggyal

+0

呃,實際上我在數據庫中存儲的不僅僅是Unicode點,但是我把它留在了這裏來簡化問題。此外,'ORD'不是Unicode兼容的,儘管我找到了一個好的選擇:http://stackoverflow.com/questions/11304582/searching-for-a-good-unicode-compatible-alternative-to-the-php- ORD-功能。 –

+0

啊,nevemind - 我的想法是在PHP的土地上。我不確定MySQL'ORD'是否兼容Unicode ... –

回答

2

由於Unicode Character Sets下記載:

的MySQL根據實施xxx_unicode_ci排序規則到在http://www.unicode.org/reports/tr10/處描述的Unicode排序算法(UCA)。排序規則使用版本4.0.0 UCA權重鍵:http://www.unicode.org/Public/UCA/4.0.0/allkeys-4.0.0.txt

full collation chart明確指出,在本整理中,基本字母的大多數變體都是等效的,而不考慮其lettercase或重音/裝飾。

如果您只想匹配確切的字母,則應使用二進制排序規則,如utf8_bin

+0

正如我在其他評論中提到的,將排序規則更改爲utf8_bin並不能解決我的問題。我不確定爲什麼...... –

+0

@David:你是否改變了「字符」列的排序規則(這真的是唯一重要的)?你也可以在查詢中明確指定一個排序規則:''WHERE'character' ='a'COLLATE utf8_bin''。 – eggyal

+0

這個伎倆。謝謝! –

1

整理中的ci表示不區分大小寫。切換到區分大小寫的排序規則(cs)以獲得您要查找的結果。

+0

默認情況下,MySQL不附帶'* _cs' Unicode排序規則。在這種情況下,Unicode二進制排序規則「* _bin」更合適。 – eggyal

+0

我切換到utf8_bin,但結果是一樣的... –

+0

沒關係 - 我實際上沒有將「字符」列的排序規則更改爲utf8_bin。當我做到了,它效果很好。 –

2

表格的整理是問題的一部分;使用_ci排序規則的MySQL將所有這些'a'視爲同一個字符的變體。

切換到_cs排序規則將強制引擎將'a'與'A'區分開,'á'與'Á'區分開,但仍可能將'a'和'á'視爲同一個字符。

如果你需要精確比較的語義,完全無視的相似字符等效,則可以使用BINARY比較運算符

SELECT id FROM unicode WHERE BINARY character = 'a' 
+0

默認情況下,MySQL不附帶'* _cs' Unicode排序規則;另外,如果匹配的字符有多個編碼(這可能發生在Unicode中,尤其是使用裝飾器),則'BINARY'將強制逐字節匹配,這可能會導致問題。在這種情況下,Unicode二進制排序規則「* _bin」更合適。 – eggyal

+0

謝謝大家。我將我的數據庫和每個表的默認排序規則更改爲utf8_bin,但問題沒有解決,但添加'BINARY'位的確有用。任何想法爲什麼? –

+0

啊,這個伎倆。我使用的是MySQL Workbench,我認爲改變一個表級聯到列的排序 - 顯然不是! –

相關問題