同一个 MariaDB 列的多个排序规则?
Posted
技术标签:
【中文标题】同一个 MariaDB 列的多个排序规则?【英文标题】:Multiple collations for the same MariaDB column? 【发布时间】:2018-02-19 06:43:04 【问题描述】:当需要不同的排序规则时,如何根据文化有效地对字符串列执行 ORDER BY?也就是说,来自不同文化的用户的数据存储在同一个表和同一列中,但每个用户自然希望看到根据其语言环境排序的数据(语言环境当然是已知的,并且在表中的每一行都是固定的)。并且表可能很长,因此列需要和索引,并且不能在应用程序端进行后处理到所需的排序规则(这是数据库任务做繁重的工作,对吧?)。
例如,utf8_general_ci
产生与 utf8_swedish_ci
不同的结果。
虽然我认为这个问题对于任何国际项目都应该是显而易见的,但我找不到任何合适的解决方案。我自己只能想象以下解决方案,它们不是很好,我怀疑没有更好的办法:
-
为每个排序规则使用单独的字段
也许,可以为每种文化创建一个视图并进行相应的索引(虽然我没有使用过 MariaDB 视图,所以这是相当理论的)
使用单独的“代理”字段进行排序,可能是 VIRTUAL
现在,如果只有一个可排序的字符串列,但可能有多个。解决此问题的预期和正确方法是什么?
【问题讨论】:
【参考方案1】:只要您使用相同的字符集(在您的情况下为utf8)进行列存储和读取,您就可以在ORDER BY column-name
子句之后使用COLLATE some-utf8-collation
:
SELECT * FROM sometable ORDER BY somecolumn COLLATE utf8_swedish_ci
在我的测试中,这会产生与德国排序规则不同的排序:
SELECT * FROM sometable ORDER BY somecolumn COLLATE utf8_german2_ci
好吧,只要数据包含相关字符,例如德语变音符号üöä。否则,您将看不到任何差异。
ORDER
子句中的多个列各有自己的COLLATE
术语:
SELECT * FROM sometable
ORDER BY
somecolumn COLLATE utf8_german2_ci,
secondcolumn COLLATE utf8_german2_ci
【讨论】:
这适用于“小”表。添加COLLATE
子句会阻止使用任何INDEX
,因为索引已经在特定的排序规则中。
哦,是的,没错。 EXPLAIN
在COLLATE
子句中使用不同的排序规则时表示“使用索引,使用文件排序”。好吧,在这种情况下,应该找到一种方法来复制所需排序规则中的相关列,同时在填充时尽量减少工作量。虚拟列在这里没有帮助,因为他们无法获得INDEX
,而持久列可以,但EXPLAIN
表示它始终在SELECT
中使用文件排序。因此,您最终将使用所需的排序规则手动填充其他列。嗯,更糟。
文件排序发生的原因有很多;看具体查询和CREATE TABLE
讨论吧。
即使对于带有索引的最简单的字符串列(无论使用或省略什么排序规则),也无法摆脱文件排序。虽然这个答案现在已经足够好了(谢谢!),但我希望得到一个涵盖使用索引进行排序的答案。但我也在使用限制,所以也许这是相关的:mariadb.com/kb/en/library/…以上是关于同一个 MariaDB 列的多个排序规则?的主要内容,如果未能解决你的问题,请参考以下文章
JPA + MariaDB:排序规则如何影响 unicode 支持?