我相信这里的很多人都知道,必须处理德语变音符号和 UTF8 归类至少可以说是有问题的。 a = ä
、o = ö
、u = ü
之类的东西不仅会影响结果的排序顺序,还会影响实际结果以及。这是一个示例,通过简单地尝试区分名词的单数和复数版本(Bademantel
- 单数,Bademäntel
- 复数),清楚地说明了事情是如何出错的).
CREATE TABLE keywords (
id INT (11) PRIMARY KEY AUTO_INCREMENT,
keyword VARCHAR (255) NOT NULL
) ENGINE = MyISAM DEFAULT CHARACTER
SET = utf8 COLLATE = utf8_unicode_ci;
INSERT INTO keywords (keyword) VALUES ('Bademantel'), ('Bademäntel');
SELECT * FROM keywords WHERE keyword LIKE ('%Bademäntel%');
结果应该是
+----+------------+
| id | keyword |
+----+------------+
| 1 | Bademäntel |
+----+------------+
然而 utf8_unicode_ci
的输出是
+----+------------+
| id | keyword |
+----+------------+
| 1 | Bademantel |
| 2 | Bademäntel |
+----+------------+
这显然不是要求的结果。
实际问题与我当前的项目有关。它涉及编写一个关键字解析器,该解析器基本上应该用指向相应产品页面的链接替换网站上每次出现的关键字。为了避免不必要的资源浪费,只获取不同的关键字,但使用任一个
SELECT keyword FROM keywords GROUP BY keyword ORDER BY LENGTH(keyword) DESC
或
SELECT DISTINCT keyword FROM keywords ORDER BY LENGTH(keyword) DESC
将导致无法处理(链接)单词的所有非变音版本,仅仅是因为它们在查询期间未获取(即所有包含 Bademäntel
的关键字将被获取,但 Bademantel
将被省略)。
现在我意识到我有几个选项可以解决这个问题。
1) 将 utf8_swedish_ci
用于关键字表或在查询期间,这将有效地使我不必修改大量现有代码。
SELECT DISTINCT keyword COLLATE utf8_swedish_ci AS keyword FROM keywords ORDER BY LENGTH(keyword) DESC;
不幸的是,我并不太愿意放弃 utf8_unicode_ci
,因为 a) 它提供了一个非常好的排序“Eszett”的功能(ss
和 ß
被认为是相同的),b)不知何故,使用瑞典语排序规则来处理与德语相关的东西感觉很不对。
2) 修改现有代码以使用utf8_bin
。
SELECT DISTINCT keyword COLLATE utf8_bin AS keyword FROM keywords ORDER BY LENGTH(keyword) DESC;
这按预期工作,但它有一个讨厌的缺点,即所有比较都区分大小写,这意味着如果我决定依赖 utf8_bin
作为问题的解决方案,我将很难做到像 LIKE('%Mäntel%')
这样的不区分大小写的查询肯定会忽略像 Bademäntel
这样的记录。
我知道这个问题时不时地出现在 SO 上,但有些答案现在已经很老了,我只想知道是否有其他解决方案可能同时出现。我的意思是,我真的无法回避允许简单的排序规则完全改变查询结果的想法。排序顺序是,但结果本身?
抱歉发帖时间较长,在此先感谢您的任何建议或评论。
最佳答案
对于遇到此问题的任何其他人,值得注意的是 since MySQL 5.6 utf8_german2_ci
排序规则有官方支持,可以解决上述所有问题。我想迟到总比不到好。
关于mysql - 重新审视德语变音符号和 UTF8 排序规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20953587/