2011-12-24 40 views
3

我有一个(Postgres)数据库表,我想添加一个手动“排序”字段。在应用程序的前端,我将有一个拖放字段,以便用户可以手动重新排序条目,然后发布一个AJAX请求,重新排序数据库中的条目,我只是想知道如何在数据库中进行编排。数据库模式:手动排序表的标准方式是什么?

例如,我能想到的最明显的选择是增加每个条目的'sort'整数,排序值> =新排序的选项,但这会过度(并且我认为,不必要地)如果这些列表超出了少数几个项目,那么数据库就会很重。

另一种选择是让“排序”列一个BigDecimal,并使其价值

SortValue[A] = SortValue[B] + (SortValue[C] - SortValue[B])/2 

其中A是我重新排序场,B是场直接在上面它和C是它下面的字段,但这似乎是一个非常混乱的解决方案,更不用说可能受小数点限制。

我确定这是一个非常普遍的问题。有效地允许手动排序数据库表的标准方法是什么?

干杯......

+0

我猜你希望用户能够手动排序;例如,将歌曲拖放到有序播放列表中。之后,您希望能够以用户选择的顺序访问或显示它们。对? – 2011-12-24 08:09:56

+0

是的,这是正确的 – PlankTon 2011-12-24 08:39:48

回答

5

假设你有这样一些数据:

id | pos 
---+---- 
8 | 1 
3 | 2 
6 | 3 
7 | 4 
2 | 5 
1 | 6 

,你想从位置5移动2到3位

所有你需要做的是这样的:

update t set pos = pos + 1 where pos >= 3 and pos < 5 

打个洞:

id | pos 
---+---- 
8 | 1 
3 | 2 
    | 
6 | 4 
7 | 5 
2 | 5 
1 | 6 

然后将此:

update t set pos = 3 where id = 2 

用于填充孔:

id | pos 
---+---- 
8 | 1 
3 | 2 
2 | 3 
6 | 4 
7 | 5 
1 | 6 

你会的,当然,都包裹在一个事务中的所有这些更新。

如果你有pos限制,以避免重复(一个好主意),那么你可以使用pos = 0作为临时值:

update t set pos = 0 where id = 2; 
update t set pos = post + 1 where pos >= 3 and pos < 5; 
update t set pos = 3 where id = 2; 

或者,如果您使用的是最新的版本的PostgreSQL(据我所知9.0 +),你可以defer your unique constraint到交易结束,而不必担心临时重复。

其他案例是相似的,留作练习。

+0

干杯亩...这样做。 – PlankTon 2011-12-24 08:38:45

0

你暗示,有没有属性在所有用户使用的数据进行排序。如果这是真的,那么我猜你不必担心列表的大小,并使用那个bigdecimal,或者只是间隔一些被调整的值的整数 - “标准化” - 回到适当的值时需要(当空间用完时)。

相关问题