2013-11-20 41 views
1

我有一個MySQL數據庫,我需要在varchar列上執行搜索。所有數據都以latin1編碼。有時這些列中有西方重音字符(對於我來說幾乎總是法語)。使用默認排序規則(latin1_swedish_ci)一直適用於我。但是現在我遇到了一些含有元音變音的數據的問題。如果我搜索「nusserhof」,我希望mysql返回「nüsserhof」,但事實並非如此。更改排序規則latin1_german1_ci解決了簡單意義上的問題,比如這個查詢工作,返回包含單詞「nüsserhof」的所有行:mysql整理latin1_german1_ci不按順序通過

select * from mytable where mycolumn like '%nusserhof%' collate latin1_german1_ci; 

但是,如果我一條一條地添加一個訂單就不再起作用。這不返回包含單詞「nüsserhof」任何行:

select * from mytable where mycolumn like '%nusserhof%' order by mycolumn collate latin1_german1_ci; 

出人意料的是,我不能在這裏或者通過谷歌這個發現任何東西。這是預期的行爲?作爲解決方法,我只是放下訂單,然後在PHP中選擇後進行排序。但似乎我應該能夠得到它的工作。

回答

0

這是預期的行爲嗎?

是的。

在瑞典,字形ü表示字母tysktÝ(「德語Y」),並且因此latin1_swedish_ci下它是字母y而非u的變型。如果應用該排序規則,您將搜索where mycolumn like '%nysserhof%',則會返回包含nüsserhof的記錄。

在德語中,字形ü表示基礎字形的重音變化(具體元音變音),並且因此下latin1_german1_ci它是字母u的變化如預期。因此,您在此排序規則下運行搜索時會獲得所需的結果。

這是由於這種地方差異,我們必須爲我們的數據選擇適當的排序規則:在一般情況下,單個排序規則總是不適用。

您從COLLATE關鍵字的誤解施加ORDER BY結果時觀察的問題:它是SELECT命令的不一部分(例如,它指示MySQL使用歸類爲命令之內的所有的比較);相反,它是緊接在前面的字符串的一部分(例如,它指示MySQL只對前面的字符串使用明確的排序規則)。

也就是說,在第一種情況下,明確的latin1_german1_ci排序規則應用於'%nusserhof%'字符串文字,coercibility爲0; mycolumn(大概是latin1_swedish_ci)的排序規則具有2的強制性。由於前者具有較低的值,因此在評估表達式時使用該值。

在第二個的情況下,明確latin1_german1_ci排序規則應用於mycolumnORDER BY子句中:這樣的排序結果將放置'nüsserhof''nu''nv'代替'ny''nz'之間。但是顯式歸類不再適用於WHERE子句中的過濾表達式,因此列的默認歸類將適用。

如果mycolumn的數據是所有在德國的語言,你可以簡單地改變其默認排序規則,不再擔心你的SQL命令中指定明確的歸類:

ALTER TABLE mytable MODIFY mycolumn <type> COLLATE latin1_german1_ci