2016-08-17 46 views
0

我有问题。这可能是理论上的。我无法理解我如何按顺序分解值,即增加表格的id字段。我有一个数据库服务器和5个客户端。他们在几个小时内同时向该表写入一些数据。数据可以包含数千个条目。Postgres的序列如何被打破?

所以...有时序列可以被打破。我的意思是它具有当前值,即不低于id字段的最大值,因此我在INSERT之后得到错误,与现有的id值有关。

E.g。有时我会遇到一个情况,当表的输入为id时,该值大于当前值sequence,该值负责为新条目返回id字段的值。这个当前值可以等于现有条目的id

我在客户端修复了这个问题。我通过查询处理错误

SELECT setval('table_id_seq', COALESCE((SELECT MAX(id)+1 FROM table), 1), false); 

但我想知道如何防止此错误的原因。

我有postgresql 9.5,在linux容器(Docker)里面启动。

+2

这不是一个错误。序列/序列不保证没有间隙。只是不*假设*他们没有差距。 – wildplasser

+0

我明白这一点。但有时序列的当前值可能小于最大ID。 – ANtlord

+0

如果您(或您的应用程序)从未分配给序列或目标列,则不会发生这种情况。 (直到环绕,当然) – wildplasser

回答

0

听起来像你的序列得到明确设置。 setval可以做到这一点,如果你设置你的序列值小于你当前的最大ID。然后,默认值与现有值冲突并出现错误。

可能发生的第二件事是您可以明确添加一个具有更大价值的ID。在这种情况下,只有在没有为该列提供值的情况下才评估该序列,并且其结束于后面。

因此,在这些情况下,请确保您从不INSERT明确的ID,并从来没有无意中调用setval。那么错误不应该发生(你可以在ID中找到空白,但是你不会得到冲突的错误)。

+0

看来我描述我的问题不是很清楚。我的错。我试图澄清。 我已经添加了'setval',当我检测到时,该序列有时可能被破坏。例如。我发现了这个问题,之后我添加了'setval'。它仅在查询完成时出错。 我也没有地方,我明确指出身份证。 – ANtlord

+0

你有多确定没有插入明确的ID?我见过很多次发生的事情是COPY命令,它们带有一个带有ID的表格,但未能设置序列。当人们推出自己的逻辑备份解决方案时,这种情况尤其常见 –

+0

顺便说一句,我有*从不*看到序列后面没有明确的id或setval的。 –