数据库模式:手动排序表的标准方法是什么?

时间:2011-12-24 07:07:16

标签: database postgresql database-design

我有一个(Postgres)数据库表,我想添加一个手动'排序'字段。在应用程序的前端,我将有一个拖放字段,以便用户可以手动重新排序条目,然后应该发布一个AJAX请求,重新排序数据库中的条目,我只是想知道如何在数据库中编排这个。

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

另一种选择是将'sort'列设为BigDecimal并使其值为

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

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

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

干杯...

2 个答案:

答案 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)

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