我相信这里的很多人都知道,至少可以说必须处理德语元音变音和 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/