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

Pla*_*Ton 4 database postgresql database-design

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

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

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

SortValue[A] = SortValue[B] + (SortValue[C] - SortValue[B])/2
Run Code Online (Sandbox Code Playgroud)

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

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

干杯...

mu *_*ort 7

假设您有一些这样的数据:

id | pos
---+----
 8 |  1
 3 |  2
 6 |  3
 7 |  4
 2 |  5
 1 |  6
Run Code Online (Sandbox Code Playgroud)

并且您想要从位置5移动2到位置3.

你需要做的就是:

update t set pos = pos + 1 where pos >= 3 and pos < 5
Run Code Online (Sandbox Code Playgroud)

打个洞:

id | pos
---+----
 8 |  1
 3 |  2
   |
 6 |  4
 7 |  5
 2 |  5
 1 |  6
Run Code Online (Sandbox Code Playgroud)

然后这个:

update t set pos = 3 where id = 2
Run Code Online (Sandbox Code Playgroud)

填补空缺:

id | pos
---+----
 8 |  1
 3 |  2
 2 |  3
 6 |  4
 7 |  5
 1 |  6
Run Code Online (Sandbox Code Playgroud)

当然,您可以将所有这些更新包含在事务中.

如果你有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;
Run Code Online (Sandbox Code Playgroud)

或者,如果您使用的是最新版本的PostgreSQL(AFAIK 9.0+),则可以将您的唯一约束推迟到事务结束,而不必担心临时副本.

其他情况类似,留作练习.