当我将UTF-8字添加到表列并执行有序SELECT时,排序顺序错误。在DESC排序上,订单是正确的,但在ASC排序时,订单是错误的。如何解决?让我解释一下这个例子。让我们有一个斯洛伐克collate的mysql表:
CREATE TABLE IF NOT EXISTS test (
aaa varchar(255) CHARACTER SET utf8 COLLATE utf8_slovak_ci NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_slovak_ci;
现在让我们插入一些UTF-8字的值:
INSERT INTO test (aaa) VALUES
('Leco'),
('Lečo'),
('Ledo'),
('Chovatelstvo'),
('Chovateľstvo')
这里是斯洛伐克语字母解释,你可以看到哪些字母在其他字母之后:http://en.wikipedia.org/wiki/Slovak_orthography
现在,当我选择订单时,我希望得到以下结果:
SELECT aaa FROM test ORDER BY aaa ASC
Chovatelstvo
Chovateľstvo
Leco
Lečo
Ledo
而且我也期望DESC的顺序完全相反。但实际上我得到的是:
SELECT aaa FROM test ORDER BY aaa ASC
Chovateľstvo
Chovatelstvo
Leco
Lečo
Ledo
和DESC:
SELECT aaa FROM test ORDER BY aaa DESC
Ledo
Lečo
Leco
Chovateľstvo
Chovatelstvo
你可以看到
Chovateľstvo
Chovatelstvo
无论ASC或DESC如何,始终按给定顺序排列。我注意到如果我以相反的顺序插入行,它可能最终为
Chovatelstvo
Chovateľstvo
意味着实际顺序相反,但ASC和DESC也是如此。就像mysql认为那两个字母'l'和'ľ'一样。
我尝试使用一些旧版本的MySQL,以及另一台服务器上最新版本的MariaDB,结果是一样的。
知道导致这种情况的原因以及解决方法吗?
答案 0 :(得分:1)
在utf8_slovak_ci
和utf8_general_ci
归类中,字母ľ
和字母l
被视为相同。
您可以通过观察此查询返回true(1)
来看到这一点select _utf8 'Chovateľstvo' collate utf8_slovak_ci = _utf8 'Chovatelstvo'
该整理的设计者显然认为ľ
和l
在字典中属于一起。我能找到的唯一没有这样做的排序是latin2_hungarian_ci
和cp1250_czech_cs
。但是要使用其中任何一个,你必须改变你的字符集选择。
如果必须让它们不同,您可以尝试utf8_bin
整理。但那将完全区分大小写。
ORDER BY
的工作方式基本上适用于整理规则。
也许整理中存在缺陷?您可以在https://bugs.mysql.com/
向MySql团队提交缺陷报告