MySQL中的自然排序

时间:2020-03-06 14:55:47  来源:igfitidea点击:

有没有一种优雅的方法可以在MySQL数据库中进行高效,自然的排序?

例如,如果我有此数据集:

  • 最终幻想
  • 最终幻想4
  • 最终幻想10
  • 最终幻想12
  • 最终幻想12:长链锁链
  • 最终幻想冒险
  • 最终幻想起源
  • 最终幻想战术

除了将游戏名称拆分成各个组成部分以外,其他任何优雅的解决方案

  • 标题:《最终幻想》
  • 编号:" 12"
  • 副标题:" Promathia的链条"

确保它们以正确的顺序出现? (10个在4之后,而不是2之前)。

这样做是一件令人痛苦的事情,因为不时有另一款游戏打破了解析游戏标题的机制(例如"战锤40,000","詹姆斯·邦德007")

解决方案

我认为这就是为什么很多东西都按发布日期排序的原因。

一种解决方案是在表中为" SortKey"创建另一列。这可能是标题的经过净化处理的版本,与我们创建的易于排序的图案或者计数器相符。

MySQL不允许这种"自然排序",因此,获得所需信息的最好方法似乎是按照上述方法拆分数据集(单独的id字段等),否则将失败然后,根据我们数据库中的非标题元素,索引元素(日期,数据库中插入的ID等)执行排序。

让数据库为我们进行排序几乎总是比将大型数据集读入我们选择的编程语言并在那里进行排序要快得多,因此,如果我们对此处的数据库模式有任何控制权,那么看看如上所述,这些字段易于排序,从长远来看,它将为我们节省很多麻烦和维护工作。

有时会在MySQL错误和讨论论坛上提出添加"自然排序"的请求,许多解决方案都围绕着剥离数据的特定部分并将其转换为查询的" ORDER BY"部分,例如

SELECT * FROM table ORDER BY CAST(mid(name, 6, LENGTH(c) -5) AS unsigned)

可以在上面的"最终幻想"示例中使用这种解决方案,但是这种解决方案不是特别灵活,并且恐怕无法完全扩展到包括"战锤40,000"和"詹姆斯·邦德007"在内的数据集。

另一种选择是在从mysql中提取数据后在内存中进行排序。从性能的角度来看,这并不是最佳选择,但如果我们不对庞大的列表进行排序,则应该没问题。

如果我们查看Jeff的文章,我们会发现很多算法可以解决我们使用的任何语言。
http://www.codinghorror.com/blog/archives/001018.html

  • 在表中添加一个排序键(等级)。 按等级排序
  • 使用"发布日期"列。 ORDER BY release_date
  • 从SQL提取数据时,请让对象进行排序,例如,如果将其提取到Set中,使其成为TreeSet,并让数据模型实现Comparable并在此处制定自然排序算法(如果使用的话,插入排序就足够了)一种没有集合的语言),因为我们将在创建模型并将其插入集合时从SQL逐行读取行)

为"排序键"添加一个字段,该字段将所有数字字符串都用零填充到固定长度,然后在该字段上进行排序。

如果我们可能有很长的数字字符串,则另一种方法是在每个数字字符串前添加数字位数(固定宽度,零填充)。例如,如果连续的位数不超过99位,那么对于" Super Blast 10 Ultra",排序键将为" Super Blast 0210 Ultra"。

刚发现这个:

SELECT names FROM your_table ORDER BY games + 0 ASC

当数字位于最前面时,进行自然排序,也可能适用于中间的排序。