顺序递增跳过数字

Posted

技术标签:

【中文标题】顺序递增跳过数字【英文标题】:Sequential increment skipping numbers 【发布时间】:2019-05-07 15:00:19 【问题描述】:
ID | info
---------
1  | xxx
2  | xxx
4  | xxx

我在 PostgreSQL 中有一个类似的设置。 (我正在使用运行 Mojavemac,如果这会有所不同的话)。

我还有一些专栏,但问题是 ID 专栏。这被设置为顺序的,所以使用 Express 我插入到数据库中。

问题是,即使插入失败,它也会在每次插入时增加 IDinfo 定义为 unique,因此尝试插入现有的 info 会返回错误。但是ID 仍然递增。

例如,如果我插入 2 行,我有 id 1id 2。然后另一个因独特违规而失败。下一个成功插入获取id = 4,跳过id = 3

我可以设置 Postgres 使其在插入失败时不会增加吗?

【问题讨论】:

您可以提供您的 Postgres 版本和您使用的实际 INSERT 语句。您的数据库的负载是多少?并发写访问与否? 序列(不仅在 postgresql 中)旨在允许多个用户同时插入唯一值(例如,用户 #1 开始事务,插入数据然后执行其他操作,然后用户 #2 开始一个事务,插入数据并提交,最后用户 #1 提交)。他们开发这样的东西几乎没有用处,因为简单的 DELETE 会破坏一切。 【参考方案1】:

serial 列,或 Postgres 10 或更高版本中的 IDENTITY,从 SEQUENCE 中抽取数字,并且可以预期会有间隙。他们的工作是通过唯一编号实现并发写入访问 - 不一定必须是无间隙编号。

如果您实际上没有并发写入访问权限,有一些简单的方法可以实现(大部分)无间隙数字。喜欢:

INSERT INTO tbl (info) 
SELECT 'xxx'
WHERE NOT EXISTS (SELECT FROM tbl WHERE info = 'xxx');

这不会从SEQUENCE 刻录序列号,因为跳过了重复插入。 (INSERT 仍可能因任何其他原因失败 - 并烧毁序列号。在这种情况下,您可以重置SEQUENCE

How to reset postgres' primary key sequence when it falls out of sync?

在单个语句中插入多行时,您还必须排除插入集合中的重复。示例代码:

Return data from subselect used in INSERT in a Common Table Expression

但是如果您确实有并发写入,原则上以上都不能可靠地工作。你最好学会接受 ID 中的空白。您可以随时使用row_number() OVER (ORDER BY id) 进行查询,以便在事后生成无间隙数字。然而,这些数字在某种程度上仍然是任意的。较小的数字不一定是较早提交的。并发写入负载下存在异常。相关:

Primary Key Value Not Incrementing Correctly Serial numbers per group of rows for compound key Auto increment table column

或者考虑使用 UUID(dat 类型 uuid)并避免在 巨大 键空间中随机值重复的固有问题。不过,serial 根本不是:

Generating a UUID in Postgres for Insert statement?

【讨论】:

你是对的,在我的情况下,差距并不重要(或者我认为大多数情况下)。谢谢你的解释!

以上是关于顺序递增跳过数字的主要内容,如果未能解决你的问题,请参考以下文章

如何跳过数组中缺少的图像? [复制]

签名认证

UIPickerView 在滚动时跳过数组中的值

剑指 Offer——1. 二维数组中的查找

如何禁止NumPy自动跳过数组的中心部分并仅打印角点

如何跳过数组的第一个和最后一个元素的循环并将它们设置为常量值?