我有一个(Postgres)数据库表,我想添加一个手动'排序'字段。在应用程序的前端,我将有一个拖放字段,以便用户可以手动重新排序条目,然后应该发布一个AJAX请求,重新排序数据库中的条目,我只是想知道如何在数据库中编排这个。
例如,我能想到的最明显的选择是为每个条目增加'sort'整数,并使用排序值> =新排序的选项,但这将是过度的(我假设,不必要的如果这些列表超过了少数几个项目,那么数据库很重。
另一种选择是将'sort'列设为BigDecimal并使其值为
SortValue[A] = SortValue[B] + (SortValue[C] - SortValue[B])/2
其中A是我正在重新排序的字段,B是它正上方的字段,C是它下面的字段,但这似乎是一个非常混乱的解决方案,更不用说可能受小数位限制的限制。
我确信这是一个非常普遍的问题。有效地允许手动排序数据库表的标准方法是什么?
干杯...
答案 0 :(得分:5)
假设你有这样的数据:
id | pos
---+----
8 | 1
3 | 2
6 | 3
7 | 4
2 | 5
1 | 6
并且您希望将2从位置5移动到位置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(AFAIK 9.0+),则可以在事务结束时defer your unique constraint,而不必担心临时副本。
其他情况类似,并留作练习。
答案 1 :(得分:0)
您暗示用户根本没有用于对数据进行排序的属性。如果这是真的那么我猜你不必担心列表的大小并使用那个大十字形,或只是整数间隔一些被调整的值 - “标准化” - 回到适当的值时需要的(当空间用完时)。