顺序递增跳过数字
Posted
技术标签:
【中文标题】顺序递增跳过数字【英文标题】:Sequential increment skipping numbers 【发布时间】:2019-05-07 15:00:19 【问题描述】:ID | info
---------
1 | xxx
2 | xxx
4 | xxx
我在 PostgreSQL 中有一个类似的设置。 (我正在使用运行 Mojave 的 mac,如果这会有所不同的话)。
我还有一些专栏,但问题是 ID
专栏。这被设置为顺序的,所以使用 Express 我插入到数据库中。
问题是,即使插入失败,它也会在每次插入时增加 ID
。 info
定义为 unique
,因此尝试插入现有的 info
会返回错误。但是ID
仍然递增。
例如,如果我插入 2 行,我有 id 1
和 id 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
:
在单个语句中插入多行时,您还必须排除插入集合中的重复。示例代码:
Return data from subselect used in INSERT in a Common Table Expression但是如果您确实有并发写入,原则上以上都不能可靠地工作。你最好学会接受 ID 中的空白。您可以随时使用row_number() OVER (ORDER BY id)
进行查询,以便在事后生成无间隙数字。然而,这些数字在某种程度上仍然是任意的。较小的数字不一定是较早提交的。并发写入负载下存在异常。相关:
或者考虑使用 UUID(dat 类型 uuid
)并避免在 巨大 键空间中随机值重复的固有问题。不过,serial 根本不是:
【讨论】:
你是对的,在我的情况下,差距并不重要(或者我认为大多数情况下)。谢谢你的解释!以上是关于顺序递增跳过数字的主要内容,如果未能解决你的问题,请参考以下文章