假设我有一个名为 的表list,其中有item这样的 s (ids 是随机 uuid):
id rank text
--- ----- -----
x 0 Hello
x 1 World
x 2 Foo
x 3 Bar
x 4 Baz
Run Code Online (Sandbox Code Playgroud)
rank我想维护列始终从 到0的属性(n-1即n行数)——如果客户端请求insert带有 的项目rank = 3,那么 pg 服务器应分别将当前的3和推送到4和:45
id rank text
--- ----- -----
x 0 Hello
x 1 World
x 2 Foo
x 3 New Item!
x 4 Bar
x 5 Baz
Run Code Online (Sandbox Code Playgroud)
我当前的策略是使用一个专用的插入函数add_item(item)来扫描表,过滤掉排名等于或大于要插入的项目的项目,并将这些排名加一。然而,我认为这种方法会遇到各种各样的问题——比如竞争条件。
是否有更标准的做法或更稳健的方法?
注意:排名列完全独立于其余列,插入并不是我需要支持的唯一操作。将其视为可排序待办事项列表的后端,用户可以动态添加/删除/重新排序项目。
逐字执行您的建议可能很困难或根本不可能,但我可以建议一种解决方法。维护一个新列ts,用于存储插入记录的时间。然后,插入当前时间以及记录的其余部分,即
id rank text ts
--- ----- ----- --------------------
x 0 Hello 2017-12-01 12:34:23
x 1 World 2017-12-03 04:20:01
x 2 Foo ...
x 3 New Item! 2017-12-12 11:26:32
x 3 Bar 2017-12-10 14:05:43
x 4 Baz ...
Run Code Online (Sandbox Code Playgroud)
现在我们可以通过查询轻松生成您想要的排序:
SELECT id, rank, text,
ROW_NUMBER() OVER (ORDER BY rank, ts DESC) new_rank
FROM yourTable;
Run Code Online (Sandbox Code Playgroud)
这将在上面的示例表中生成 0 到 5 的排名。基本思想是只使用已经存在的rank列,但如果相同的排名出现多次,则让时间戳打破排序的平局。
| 归档时间: |
|
| 查看次数: |
3369 次 |
| 最近记录: |