避免在多台机器中重复增加 SERIAL 列

Posted

技术标签:

【中文标题】避免在多台机器中重复增加 SERIAL 列【英文标题】:Avoid duplicate increment in SERIAL column in mutiple machines 【发布时间】:2014-04-20 14:47:15 【问题描述】:

现在我在单台机器上安装了 Postgres 并创建了一个带有 serial 列的表。每当插入新行时,此列就会自动增加。如果我在另一台机器上安装 Postgres 以进行分布式计算并使用serial 列创建同一个表,serial 列从 1 开始?或者我可以为列设置最小值(第一台机器的最大值+1)?

【问题讨论】:

【参考方案1】:

默认情况下,SERIAL 创建一个以 1 开头的 SEQUENCE

如果需要,您可以修改序列,使每台机器都有一个不同的起始值,并且所有序列在创建表后都有一个偏移量。例如,ALTER SEQUENCE the_sequence_name START WITH 2 INCREMENT BY 10。给每台机器设置不同的START WITH 值并确保它们都具有相同 INCREMENT BY。这样可以保证每台机器都获得唯一的 ID。

如果您这样做,您可能希望使用bigint 键列,并分配像INCREMENT BY 1000 这样的大偏移量。这样一来,当您必须添加机器 #11 时,您就不会感到痛苦。

另一种选择是使用uuid 主键。

【讨论】:

考虑我对STARTRESTART 的回答。【参考方案2】:

请注意,ALTER SEQUENCE 中的 START 子句仅设置默认起始值​​。它确实不会改变序列的当前值,这是一种常见的误解。

如果您在CREATE SEQUENCE 语句中使用该子句,则该序列将使用START 值进行初始化,并按预期运行:第一次调用nextval() 将在此处返回7

CREATE SEQUENCE foo_seq START WITH 7 INCREMENT BY 16;

但是,如果您运行ALTER SEQUENCE,则序列已经初始化为其他值(默认为 1),您需要添加一个 RESTART子句来实际重置序列:

ALTER SEQUENCE foo_seq START WITH 7 INCREMENT BY 16 <b>RESTART</b>;

Per documentation:

重启

可选子句RESTART [ WITH restart ] 更改序列的当前值。这相当于调用setval 带有is_called = false的函数:将返回指定的值 下次拨打nextval。写RESTART 没有重启值是 相当于提供CREATE记录的起始值 SEQUENCE 或最后由ALTER SEQUENCE START WITH 设置。

当您更改为 serial 列隐式创建的序列时,这就是您所需要的。 这也是您真正需要的问题:

ALTER SEQUENCE foo_seq <b>RESTART WITH max_of_other_tbl</b>;

SQL FIDDLE demonstrating the variants.

【讨论】:

我会选择 2 的幂作为增量。这将导致(假设的)环绕仅对本地安装产生影响,而不是与对等方发生冲突。 @wildplasser:有效的考虑。不花钱,有收获。我相应地调整了我的例子。 我还没有体验过我的第一个环绕式连续剧。但我不希望它成为一个多安装问题(还记得 Oracle 高水印的事情......?)

以上是关于避免在多台机器中重复增加 SERIAL 列的主要内容,如果未能解决你的问题,请参考以下文章

如何使用Tomcat从属性文件中检索数据库属性以便在多台机器上工作[重复]

在 PySpark 中连接两个数据框时避免列重复列名

如何避免列中重复出现

使用 Not exists SQL ORACLE 避免列重复

在 SQL Server [Moodle] [PHP] 中显示所有但避免重复 DB 列记录

如何使MongoDB的列成为SQL Server中发生的主键,避免重复记录?