对包含varchar列中的文本和数字的数据进行排序

时间:2012-07-24 01:06:51

标签: mysql sorting

我在MySQL数据库中有一个varchar列,它存储了一些可以包含任何字符和数字的文本。

架构使用utf8作为字符集,utf8_unicode_ci作为整理。 InnoDB用作数据库引擎,因为我需要使用事务。

我想做的是能够以自然的方式ORDER BY该列。例如,这里有一些示例数据:

12234 some random text
my text 23
mytext3
123456abcd
text23
text1
text111
text33

将测试数据插入测试表后,我运行查询并ORDER BY varcharASC

SELECT * FROM `test` WHERE 1 ORDER BY data ASC;

问题在于没有考虑数字的“大小”:

12234 some random text
123456abcd
my text 23
mytext3
text1
text111 <-------
text23
text33

然后我在这里发现了这个question提供了(几乎)解决方案:

SELECT * FROM `test` WHERE 1 ORDER BY data * 1 DESC;

123456abcd             <------ These 2 should
12234 some random text <------ be swapped
my text 23
mytext3
text23
text1
text33
text111

上面的另一个缺点是上面的内容不能使用任何索引,因为每行都有一个opreation。

我也不确定一旦我们介绍非拉丁字符会有什么影响。

有没有一种高效的方法让MySQL进行自然语言排序?

1 个答案:

答案 0 :(得分:0)

你问:

   Is there a performant way to get MySQL to perform natural language sorting?

简答:不。

更长的答案:

据推测,您希望MySQL以使用所选排序规则和数字文本处理非数字文本的方式整理您的日期,就好像它是二进制数字一样。

您需要创建某种代理键进行整理,并将其存储在自己的列中。您可以通过转换每个文本字符串来完成此操作,并将原始字符串和代理键字符串加载到dbms中。

Original Text                   Surrogate Key Text
12234 some random text          0000012234 some random text
my text 23                      my text 0000000023
mytext3                         mytext0000000003
123456abcd                      0000123456abcd
text23                          text0000000023
text1                           text0000000001
text111                         text0000000111
text33                          text0000000033
1text123                        0000000001text0000000123
2text124                        0000000002text0000000124

请注意,在此示例中,样本中的每个数字数据块都填充为十位十进制数字。

加载DBMS时,这在您的应用程序中最容易实现。您可以编写一个简单的字符串解析例程来完成它。您没有告诉我们您正在使用的应用程序语言。

如果您只在每个查询中整理有限数量的记录,则在检索记录后也可以在您的应用程序中进行记录。