我想在表中存储一个附加列作为“排序值”,它是标题列的数字表示,这样这些值的顺序代表字符串的自然字母排序顺序。即,这样我就可以检索按排序值排序的行,它们将按自然排序顺序排列 - 当我插入新行时,我可以生成数值并且知道相对于其他值的值将代表字符串的位置在字母搜索中,精确到前 X 个字母左右。
这样做有几个原因:首先,我想要一个比数据库服务器提供的普通排序更自然的排序,在数据库服务器中,像“The”和“A”以及标点符号这样的东西在开始时被忽略,数字是“自然”对待。
其次,这适用于具有大量排列的索引 - 它将节省空间,并可能在遍历具有许多行的索引时节省时间。
我所追求的是将字符串转换为该数值的算法,或者我想,只是一个规范化的字符串值。
我正在使用 PHP 和 MySQL。
我担心“从数据库中提取所有内容并使用 natcasesort() 在 PHP 中排序”不是针对这种特定情况的解决方案,因为我想在排序中检索行(使用排序依据和分组依据)在他们到达连接或限制条款之前订购。谢谢。
编辑:
感谢到目前为止的回答。我刚刚想到我的应用程序使用 UTF-8 这一事实非常重要。话虽如此,我认为以压缩/数字形式表示字符串的初始部分的实用性是一种延伸,也许只是某种规范化形式(所有大小写折叠,数字零填充,以及尽可能多的字符)归一化到它们的根,即 ã 到 a) 是合适的。
最佳答案
“准确到前 X 个字母左右” 部分很关键,因为完全准确地分配数字是不可能的。要看到这一点,具体来说,假设您的 title
列是 varchar(50)
并且您想要使用 32 位 integer
sort_order
列。然后您可以存储 (255^51 - 1) 个不同的标题,每个标题都需要不同的 sort_order
值——但是只有 2^32 个不同的 sort_order
值可以四处走走。即使您说您永远不会添加超过 2^32 行,您也需要提前知道他们将拥有哪些标题,以便提出一个避免必须重新分配所有 sort_order
值的方案每次插入一行。
虽然“理论上完美”的解决方案是不可能的,但仍然有可能获得一个实用的“近似”系统,该系统应该可以完美准确地处理多达数百万行。最简单的方法是使用浮点类型。最初,按排序顺序列出行,并为第一行分配 sort_order
值 1.0,第二行分配值 2.0,依此类推。然后,每当插入一行时,将其 sort_order
设置为排序顺序中任一侧行的中点(即平均值)。如果新添加的行位于所有现有行之前(或之后),只需将其设置为小于(或大于)先前最小(或最大)sort_order
值的 1。
最好从头开始重新分配数字(如在初始构建步骤中)以定期或在大量更新后“平滑”值。特别是如果表格开始时很小然后变大,您可能会在末尾发现一些数字“成串”。
关于mysql - 获取字符串的数字/规范化表示以帮助 DB 中标题的 'natural sort ordering',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/591256/