Sql 将值插入表中,确定可用的最小值

Sql 将值插入表中,确定可用的最小值,sql,postgresql,Sql,Postgresql,我有一个Postgres表,它保存用户信息,该表中的字段为: id (int) name (string) 我希望能够添加一个用户,并向他提供一个ID,该ID将从表中的当前值延迟: 将提供给添加用户的ID应该是表中可用的最小ID,即如果我有一个具有以下ID的表:1、3、4、5、8, 我希望该用户的ID为2,下次我将添加一个用户,其ID为6,下一个ID为7,依此类推 什么是正确的查询?下面的select查询可用于从表中查找缺少的ID SELECT t FROM generate_series(

我有一个Postgres表,它保存用户信息,该表中的字段为:

id (int) 
name (string)
我希望能够添加一个用户,并向他提供一个ID,该ID将从表中的当前值延迟:

将提供给添加用户的ID应该是表中可用的最小ID,即如果我有一个具有以下ID的表:1、3、4、5、8, 我希望该用户的ID为2,下次我将添加一个用户,其ID为6,下一个ID为7,依此类推


什么是正确的查询?

下面的select查询可用于从表中查找缺少的ID

SELECT t
FROM generate_series((
            SELECT min(id) + 1
            FROM tb
            ), (
            SELECT max(id) + 1
            FROM tb
            )) t
WHERE NOT t IN (
        SELECT id
        FROM tb
        )
ORDER BY t ASC
插入可以通过以下方式完成:

INSERT INTO tb
VALUES (
    (
        SELECT t
        FROM generate_series((
                    SELECT min(id) + 1
                    FROM tb
                    ), (
                    SELECT max(id) + 1
                    FROM tb
                    )) t
        WHERE NOT t IN (
                SELECT id
                FROM tb
                )
        ORDER BY t ASC limit 1
        )
    ,'B'
    )

创建这样一个函数

    CREATE OR replace FUNCTION missed_id ()
RETURNS INTEGER AS $$
SELECT t
FROM generate_series((
            SELECT min(id) + 1
            FROM tb
            ), (
            SELECT max(id) + 1
            FROM tb
            )) t
WHERE NOT t IN (
        SELECT id
        FROM tb
        )
ORDER BY t ASC limit 1;;$$
LANGUAGE sql
而insert应该是

insert into tb values (missed_id(),'B')

下面的select查询可用于从表中查找缺少的ID

SELECT t
FROM generate_series((
            SELECT min(id) + 1
            FROM tb
            ), (
            SELECT max(id) + 1
            FROM tb
            )) t
WHERE NOT t IN (
        SELECT id
        FROM tb
        )
ORDER BY t ASC
插入可以通过以下方式完成:

INSERT INTO tb
VALUES (
    (
        SELECT t
        FROM generate_series((
                    SELECT min(id) + 1
                    FROM tb
                    ), (
                    SELECT max(id) + 1
                    FROM tb
                    )) t
        WHERE NOT t IN (
                SELECT id
                FROM tb
                )
        ORDER BY t ASC limit 1
        )
    ,'B'
    )

创建这样一个函数

    CREATE OR replace FUNCTION missed_id ()
RETURNS INTEGER AS $$
SELECT t
FROM generate_series((
            SELECT min(id) + 1
            FROM tb
            ), (
            SELECT max(id) + 1
            FROM tb
            )) t
WHERE NOT t IN (
        SELECT id
        FROM tb
        )
ORDER BY t ASC limit 1;;$$
LANGUAGE sql
而insert应该是

insert into tb values (missed_id(),'B')
这是一个坏主意,如果您同时插入,那么它不是事务安全的


这是一个坏主意,如果您同时进行插入,那么它不是事务安全的

为什么您认为您需要这样做?无间隙ID通常是一个坏主意,因为它很难正确实现,如果您这样做,它的速度非常慢,并且无法在多用户环境中扩展。我需要它,因为我希望我的ID尽可能有序。我不在乎速度和效率。你为什么要“订购”?主键的唯一用途是唯一标识表中的行。PK不需要“有序”(甚至无间隙)。你想用这个解决的真正问题是什么?你为什么认为你需要这个?无间隙ID通常是一个坏主意,因为它很难正确实现,如果您这样做,它的速度非常慢,并且无法在多用户环境中扩展。我需要它,因为我希望我的ID尽可能有序。我不在乎速度和效率。你为什么要“订购”?主键的唯一用途是唯一标识表中的行。PK不需要“有序”(甚至无间隙)。您试图解决的真正问题是什么?如果没有丢失的id怎么办如果丢失了多个id,则会发生PBoom,您还应该进行一些限制,并且不要忘记排序:)您忘记了
锁定表。只有先锁定表才能远程安全。如果没有丢失的id怎么办如果丢失了多个id,则会发生PBoom,您还应该进行一些限制,并且不要忘记排序:)您忘记了
锁定表。只有先锁定表,才能实现远程安全。