Mysql和LDML(与latin1相同的加入字符)

时间:2016-05-25 09:51:41

标签: mysql utf-8 collation

我使用utf8_slovenian_ci作为列和表的排序规则。一切都很好,除了č和c被视为不同的字符(和其他2个斯洛文尼亚特定字符)。

他们在分类和意义上有所不同!但是出于搜索原因,在手机上很难选择č所以我希望那些非香薰的角色表现得像香水一样:

C = C S =š Z =ž

反之亦然,不区分大小写。

我读到了在mysql中使用LDML扩展排序规则,但我无法在搜索引擎中制作“bograč”=“bograc”。

有人能帮助我吗?

更新

为了简化问题,是否可以使用c =č进行搜索,č是在c之后使用LDML进行排序?我可以修改内置的排序规则,还是需要制作新的排序规则?

更新2

我没有搜索的简化查询(例如所有食谱名称)是:

SELECT * from recipes order by RecipeName COLLATE 'utf8_slovenian_ci' asc limit 5

我得到解释:

Rows: 20.000, Extra: Using filesort

如果我不使用斯洛文尼亚整理(我现在在RecipeName上有general_ci),我得到:

Rows: 5, Extra: Using Index

如果我使用WHERE LIKE ='%soup%'搜索,我仍然会在20.000行上获取filesort,因为它似乎是整个结果集中的mysql filesorts。

唯一的方法是在RecipeName列上排序使用2列,一个general_ci和一个slovenian_ci并使用一个进行搜索(作为我的全文搜索的一部分 - 这个例子是简化的),另一个用于排序时间我想通过RecipeName订购?或者这仍然是整个20.000食谱的文件?

2 个答案:

答案 0 :(得分:1)

我没有测试,但utf8_general_ci排序规则对重音不敏感,应该按照您想要的方式进行搜索。

为获得最佳效果,您可以在表格中创建一个utf8_general_ci的单独列,然后搜索:

 real_column     search_column
 -----------------------------------
 bograč          bograč

然后以下内容应该有效:

 SELECT real_column FROM table WHERE search_column = "bograc"

 > bograč

或者,COLLATE应该可以工作(但是懒散!)。像这样:

 SELECT real_column FROM table
 WHERE real_column COLLATE utf8_general_ci = "bograc";

答案 1 :(得分:1)

列上的COLLATION用于搜索(WHERE ...)和排序(ORDER BY);没有办法有效地为一个列提供两种不同的排序规则。

如前所述,您可以在COLLATE ...上使用其中一种案例中的其他排序规则。但这可能不会使用索引。但是,如果你正在阅读整个表格,那么加上COLLATE ...不会对表现造成太大影响。 (很少使用索引来访问表格中的大部分内容。)

如前所述,2列是可能的。一个用于搜索并拥有COLLATE utf8_general_ci并拥有自己的INDEX。另一个将具有相同的文本,但是COLLATE utf8_slovenian_ci并且具有单独的索引。 可能对排序很有用。

如何进行分类?你会拿整张桌子吗? (请参阅上面的说明。)或者您是否会过滤掉20行,然后在“正确的”字样中对它们进行排序。斯洛文尼亚方式?排序20行并不耗时。 (见上面的其他说明。)

因此,我建议声明列utf8_general_ci并在需要排序的查询中包含COLLATE子句。如果这还不够,请提供详细信息 - 查询和SHOW CREATE TABLE。然后我们可以进一步讨论这个问题。

http://mysql.rjweb.org/utf8_collations.html提供了两种排序规则(以及其他排序规则)的详细信息。我看到Ø也像单独的字母一样,与ČŠŽ一样。

更多

根据我的理解你的要求,你(1)用重音剥离搜索所有20K行,然后(2)使用utf8_slovenian_ci collat​​ion对子集进行排序。由于步骤1的成本更高,因此为整体性能设置整理效果更好。例如,如果只有5行需要排序,那么应用COLLATE utf8_slovenian_ci将是一个很小的代价。

更多#2

我之前的评论未考虑WHERE使用的是领先的通配符。

假设您有20,000行,查询检索500行。例如:WHERE col LIKE '%soup%' ORDER BY col。领先的通配符是这种情况下的一个重要因素。

将查看20.000行以执行WHERE无论的排序规则。我不知道COLLATE条款的成本是多少。领先通配符的成本可能高于整理通行证的成本。

500行可能使用也可能不使用索引。如果列声明与ORDER BY所需的排序规则匹配,则优化程序可以使用索引。 (如果整理不同意,则不能使用索引进行排序。)

由于声明的排序规则可能对其中一个(WHEREORDER BY)有帮助而对另一个有所帮助,因此很难预测哪个更好。我建议尝试两种方式:

col VARCHAR ... COLLATE utf8_general_ci
WHERE col LIKE '%soup%'
    ORDER BY col COLLATE utf8_slovenian_ci
-- versus --
col VARCHAR ... COLLATE utf8_slovenian_ci
WHERE col LIKE '%soup%' COLLATE utf8_general_ci
    ORDER BY col

另一方面,如果您有两列:

col_for_display VARCHAR ... COLLATE utf8_slovenian_ci
col_for_searching VARCHAR ... COLLATE utf8_general_ci

然后这样做:

SELECT col_for_display
    WHERE col_for_searching LIKE '%soup%'
    ORDER BY col_for_display

那应该使用WHERE的索引(但由于前导通配符,仍会扫描整个表)。它不能使用ORDER BY的任何索引,但col_for_display会知道如何正确排序。

同样,我无法预测此选项是否足够快于其他两个选项。

底线:我认为没有办法得到你想要的东西,即使是新的整理也是如此。遗憾。