如何获取PostgreSQL序列中的下一个数字
我想为PostgreSQL做些什么。我明白在PostgreSQL中,作者不会阻止读者。那么,如何安全地增加表中的序列呢。我知道PostgreSQL有一个序列功能,但我不想找它,因为这样我就可以在数据库中创建数千个序列 我有一张这样的桌子:如何获取PostgreSQL序列中的下一个数字,sql,postgresql,postgresql-9.4,Sql,Postgresql,Postgresql 9.4,我想为PostgreSQL做些什么。我明白在PostgreSQL中,作者不会阻止读者。那么,如何安全地增加表中的序列呢。我知道PostgreSQL有一个序列功能,但我不想找它,因为这样我就可以在数据库中创建数千个序列 我有一张这样的桌子: +----+-----------+------+-------+--+ | id | Part | Seq | Model | | +----+-----------+------+-------+--+ | 1 | Head |
+----+-----------+------+-------+--+
| id | Part | Seq | Model | |
+----+-----------+------+-------+--+
| 1 | Head | 0 | 3 | |
| 2 | Neck | 1 | 3 | |
| 3 | Shoulders | 2 | 29 | |
| 4 | Shoulders | 2 | 3 | |
| 5 | Stomach | 5 | 3 | |
+----+-----------+------+-------+--+
对于型号3,如何在gast
之后插入另一条带有下一个seq的记录。下面是新表的外观:
+----+-----------+------+-------+--+
| id | Part | Seq | Model | |
+----+-----------+------+-------+--+
| 1 | Head | 0 | 3 | |
| 2 | Neck | 1 | 3 | |
| 3 | Shoulders | 2 | 29 | |
| 4 | Shoulders | 2 | 3 | |
| 5 | Stomach | 5 | 3 | |
| 6 | Groin | 6 | 3 | |
+----+-----------+------+-------+--+
是否有一种方法可以创建一个insert查询,该查询只会给出型号3的最高序号之后的下一个数字。另外,要查找并发安全的内容。您可以使用
as
关键字在insert语句中查询表。您可以找到完整的语法,但在本例中,您需要的语法是insert-into()
为了确保其他会话无法运行类似的查询,听起来您需要(SRE)锁。根据文件:
此模式保护表不受并发数据更改的影响,并且是自排他的,因此一次只能有一个会话保存它
SRE锁与其他行独占(RE)锁发生冲突,这些锁是在任何插入期间获得的,但仍允许从表中读取。但是,重锁本身不会阻止其他会话同时执行插入,因此简单的插入不足以防止并发更改
SRE锁通常通过更改表或创建触发器自动获得,但也可以手动创建。您需要在插入之前获得锁,然后通过尽快提交更改来释放它
例如:
begin work;
lock table my_table in share row exclusive mode;
insert into my_table
(id, part, seq, model) as
select
max(id) + 1 as id,
'Next Body Part' as part,
max(seq) + 1 as seq,
4 as model
from
my_table;
commit work;
需要注意的是,这不会阻止应用程序获取max序列(在上述语句运行之前或运行期间),然后处理该序列并使用该变量创建新的insert语句。(例如,
?如seq
,绑定参数为$max\u sequence+1
)。为了确保它保持并发,您需要确保在同一个insert语句中获得序列号,或者至少在应用程序具有SRE锁时获得序列号。有,如果您确实需要,是否有方法锁定特定行?我有一张大桌子,不想把整张桌子都锁上。我想在锁定行时防止读写。听起来你可能需要一个共享独占锁。我已经更新了帖子,以反映这将如何工作。您仍然可以阅读,但是如果您介意最后提到的警告,那么并发性就不会有问题。