postgresql Recycle ID номера - PullRequest
1 голос
/ 13 мая 2011

У меня есть следующая таблица

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

По сути, это создает «группу», с которой связываются идентификаторы пользователей, поэтому, когда я хочу запросить членов группы, я могу вызвать таблицу.

Пользователи могут покинуть группу и создать новую.

Когда все пользователи покинули группу, в моей таблице больше нет идентификатора группы.

Предположим, это для приложения чата, где пользователи могут постоянно закрывать и открывать чаты, идентификаторы групп будут складываться очень быстро, но количество чатов реально не достигнет миллионов чатов с сотнями пользователей.

Я хотел бы переработать номера идентификаторов групп, чтобы при вставке новой записи, если группа 4 не использовалась (как в случае выше), ей присваивались.

1 Ответ

3 голосов
/ 14 мая 2011

Есть веские причины не делать этого, но в 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;

Этот запрос вернет NULL, если пропусков нет или если строк нетвсе в таблице "группы".Если вы хотите использовать это для возврата следующего идентификатора группы независимо от состояния таблицы "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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...