我使用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食谱的文件?
答案 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 collation对子集进行排序。由于步骤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
所需的排序规则匹配,则优化程序可以使用索引。 (如果整理不同意,则不能使用索引进行排序。)
由于声明的排序规则可能对其中一个(WHERE
或ORDER 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
会知道如何正确排序。
同样,我无法预测此选项是否足够快于其他两个选项。
底线:我认为没有办法得到你想要的东西,即使是新的整理也是如此。遗憾。