在SQL中存储排序顺序的最佳方法是什么?

时间:2010-05-13 01:38:53

标签: sql database sorting

顶部的人希望排序顺序可以在我们的应用程序中自定义。所以我有一个有效定义数据类型的表。存储排序顺序的最佳方法是什么?如果我刚刚创建了一个名为“Order”的新列,那么每当我更新一行的顺序时,我想我必须更新每一行的顺序以确保后代。有没有更好的方法呢?

5 个答案:

答案 0 :(得分:13)

到目前为止,没有一个答案涉及自定义排序顺序的真正问题,而当两个不同的人希望以不同方式排序相同的记录时会发生这种情况。

如果您需要自定义排序顺序,则需要一个相关表来存储它,而不是其他字段。该表将具有userid,数据的recordId和记录的排序顺序。这样,Joe Smith可以拥有一个订单而Sally Jones可以获得相同的数据。现在您遇到了将新记录添加到数据集的问题。您是将它们放在排序顺序的开头还是结尾处,或者您是否需要此人为它们设置订单才能将它们添加到集合中。这实际上是一个非常复杂的问题,通常不值得花时间来实现,因为几乎没有人使用该系统一旦到位(我的意思是我真的想要通过一百条记录并标记个人每个人的顺序?)。现在它在保存所有记录的顺序方面变得复杂了(当然,在下次运行查询时需要更改,因为会有新的记录。)这是一个非常痛苦的有限直到过程。

我在撰写应用程序的提案中做了一次,因为我们需要能够按照我们认为对客户最令人印象深刻的顺序对提案中的部件和任务进行排序。即使这样,我们也必须制定一个默认订单,这样他们只需要先移动他们真正想要出现的两三件事,而不是订购10,000件零件。

如果你可以让它们买断,更好的选择是允许他们按列(desc或asc)对数据进行排序。通常可以设计用户界面,以便在单击列标题时,它将按该列求助数据。这样做相对简单,满足了定制订购的大多数需求。

你真的需要与管理层讨论这个要求,并获得他们希望如何工作的细节,我想要自定义订购。这通常是人们认为他们想要的东西之一,但并没有真正使用。

答案 1 :(得分:7)

基本算法可能如下所述。最初,排序字段因项目而异1000(您可以考虑另一个间隔)。 为简单起见,表中的项目处于有序状态。 顺便说一下,我创建Yii2 component来管理这些东西。如果你需要一个可排序的树sortable tree,那就是这个。

id | sort
---+-----
1  | 1000
---+-----
2  | 2000
---+-----
3  | 3000
---+-----

假设我们要在id 1之后添加一个项目(id 4):

id | sort
---+-----
1  | 1000
---+-----
4  | 1500
---+-----
2  | 2000
---+-----
3  | 3000
---+-----

因此,为了计算id 4的排序值,我们采用了之前项目的排序值,即1000 以及2000年以后的项目并采取了平均值。如果你得到一个浮点数,只需将它四舍五入到最接近的整数。 如果你需要在列表的开头插入一个项目,那么你取一个平均值(1000和0,即500)。

现在,如果我们需要在id 1之后插入一个项目(id 5),我们也会这样做:

id | sort
---+-----
1  | 1000
---+-----
5  | 1250
---+-----
4  | 1500
---+-----
2  | 2000
---+-----
3  | 3000
---+-----

稍后,您可能面临这种情况:

id | sort
---+-----
1  | 1000
---+-----
15 | 1001
---+-----
...
---+-----
5  | 1250
---+-----
...
---+-----

因此,如果您需要在1到15之间插入一个项目(ID 16),首先应该将排序字段增加1000个所有项目后跟1:

id | sort
---+-----
1  | 1000
---+-----
15 | 2001
---+-----
...
---+-----
5  | 2250
---+-----
...
---+-----

现在您可以插入项目(ID 16):

id | sort
---+-----
1  | 1000
---+-----
16 | 1501
---+-----
15 | 2001
---+-----
...
---+-----
5  | 2250
---+-----
...
---+-----

答案 2 :(得分:1)

使用int字段。更新一行的排序顺序时,只需更新要更新的行上的字段以及行的旧位置和新位置之间的任何行。这意味着仅交换两行涉及触摸这两行。此外,对于您正在更新的不是“活动”行的行,您只需要递增或递减该字段;查询很容易写。

答案 3 :(得分:0)

您可以使用浮点数,只要您有足够的精度,您就可以随时将移动记录的序号列设置为两侧记录之间的中点。

答案 4 :(得分:0)

通常,应用程序会将approriate ORDER BY子句添加到查询中。如果要排序的结果集相对较小,则可以在选择条件上使用键。即使结果很大,通常也可以对所选数据进行排序,而不是按索引按顺序检索。

如果要求的订单类似于B A Z T Q M K,那么您需要一个列来放置相对订单。每次添加行时都需要确定适当的值。但是,这适用于相对静态的代码表。