2017-09-11 32 views
0

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

例如,utf8_general_ciutf8_swedish_ci产生不同的结果。

虽然我认为这个问题对于任何国际项目都是显而易见的,但我找不到任何合适的解决方案。我自己,我才能成像只有下面的解决方案,这是不是很好,我怀疑没有更好的可以做:

  1. 使用一个单独的领域每个比
  2. 也许,一个视图可以为每个文化创建和索引因此(我还没有和MariaDB的意见虽然工作,所以这是很理论的)
  3. 使用一个单独的“代孕”现场只是为了整理,也许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 
+0

这是罚款,“小”表。因为索引已经处于特定的排序规则中,因此对COLLATE子句的处理会阻止使用任何INDEX。 –

+0

哦,是的,这是正确的。当在COLLATE子句中使用不同的排序规则时,'EXPLAIN'说“使用索引,使用filesort”。那么,在这种情况下,应该找到一种方法来复制想要的归类中的相关列,同时尽量减少填充时的工作量。虚拟列在这里没有帮助,因为它们不能得到一个'INDEX',一个持久列可以,但是'EXPLAIN'说它总是在'SELECT'中使用filesorting。因此,您最终将手动填充所需归类的其他列。呃,更糟糕。 – Anse

+0

Filesort发生的原因很多;让我们看看具体的查询和“CREATE TABLE”来讨论它。 –