数据库
首页 > 数据库> > mysql – 重新访问德语变音符号和UTF8排序规则

mysql – 重新访问德语变音符号和UTF8排序规则

作者:互联网

我确信这里的很多人都知道,至少可以说,不得不处理德语变音符号和UTF8校对可能会有问题.像a =ä,o =ö,u =ü这样的东西不仅能够影响结果的排序顺序,还能影响实际结果.这是一个例子,通过简单地试图区分名词的单数和复数版本(Bademantel – singular,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,collation,diacritics
来源: https://codeday.me/bug/20190703/1366446.html