【问题标题】:Multiple collations for the same MariaDB column?同一个 MariaDB 列的多个排序规则?
【发布时间】:2018-02-19 06:43:04
【问题描述】:

当需要不同的排序规则时,如何根据文化有效地对字符串列执行 ORDER BY?也就是说,来自不同文化的用户的数据存储在同一个表和同一列中,但每个用户自然希望看到根据其语言环境排序的数据(语言环境当然是已知的,并且在表中的每一行都是固定的)。并且表可能很长,因此列需要和索引,并且不能在应用程序端进行后处理到所需的排序规则(这是数据库任务做繁重的工作,对吧?)。

例如,utf8_general_ci 产生与 utf8_swedish_ci 不同的结果。

虽然我认为这个问题对于任何国际项目都应该是显而易见的,但我找不到任何合适的解决方案。我自己只能想象以下解决方案,它们不是很好,我怀疑没有更好的办法:

  1. 为每个排序规则使用单独的字段
  2. 也许,可以为每种文化创建一个视图并进行相应的索引(虽然我没有使用过 MariaDB 视图,所以这是相当理论的)
  3. 使用单独的“代理”字段进行排序,可能是 VIRTUAL

现在,如果只有一个可排序的字符串列,但可能有多个。解决此问题的预期和正确方法是什么?

【问题讨论】:

    标签: mysql mariadb collation culture


    【解决方案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,因为索引已经在特定的排序规则中。
    • 哦,是的,没错。 EXPLAINCOLLATE 子句中使用不同的排序规则时表示“使用索引,使用文件排序”。好吧,在这种情况下,应该找到一种方法来复制所需排序规则中的相关列,同时在填充时尽量减少工作量。虚拟列在这里没有帮助,因为他们无法获得INDEX,而持久列可以,但EXPLAIN 表示它始终在SELECT 中使用文件排序。因此,您最终将使用所需的排序规则手动填充其他列。嗯,更糟。
    • 文件排序发生的原因有很多;看具体查询和CREATE TABLE讨论吧。
    • 即使对于带有索引的最简单的字符串列(无论使用或省略什么排序规则),也无法摆脱文件排序。虽然这个答案现在已经足够好了(谢谢!),但我希望得到一个涵盖使用索引进行排序的答案。但我也在使用限制,所以也许这是相关的:mariadb.com/kb/en/library/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-20
    • 2017-04-26
    • 2023-04-11
    • 1970-01-01
    • 2018-12-06
    • 1970-01-01
    相关资源
    最近更新 更多