postgresql回收ID号

时间:2011-05-13 16:38:37

标签: postgresql

我有一张表如下

|GroupID | UserID |
--------------------
|1       | 1      |
|1       | 2      |
|1       | 3      |
|2       | 1      |
|2       | 2      |
|3       | 20     |
|3       | 30     |
|5       | 200    |
|5       | 100    |

基本上它的作用是创建一个与用户ID相关联的“组”,因此当我希望请求组的成员时,我可以在桌面上调用。

用户可以选择离开组并创建新组。

当所有用户都离开了一个组时,我的表中不再有该groupID。

让我们假设这是一个聊天应用程序,用户可能会关闭并不断打开聊天记录,组ID将非常快速地加起来,但聊天的数量实际上不会达到数百万用户的数百次聊天。

我想回收群组ID号码,这样当我转到插入新记录时,如果未使用群组4(如上所述),则会被分配。

1 个答案:

答案 0 :(得分:3)

有充分的理由不这样做,但在PostgreSQL中它非常简单。该技术 - 使用generate_series()来查找序列中的间隙 - 在其他情况下也很有用。

WITH group_id_range AS (
    SELECT generate_series((SELECT MIN(group_id) FROM groups), 
                           (SELECT MAX(group_id) FROM groups)) group_id
)
SELECT min(gir.group_id)
FROM group_id_range gir
LEFT JOIN groups g ON (gir.group_id = g.group_id)
WHERE g.group_id IS NULL;

如果表“groups”中没有间隙或者根本没有行,那么该查询将返回NULL。如果您想使用它来返回下一个组ID号,而不管表“groups”的状态如何,请改用它。

WITH group_id_range AS (
    SELECT generate_series(
                      (COALESCE((SELECT MIN(group_id) FROM groups), 1)), 
                      (COALESCE((SELECT MAX(group_id) FROM groups), 1))
                  ) group_id
)
SELECT COALESCE(min(gir.group_id), (SELECT MAX(group_id)+1 FROM groups))
FROM group_id_range gir
LEFT JOIN groups g ON (gir.group_id = g.group_id)
WHERE g.group_id IS NULL;