【问题标题】:Postgresql: why no automatic updates of a id sequence after bulk insertPostgresql:为什么批量插入后没有自动更新id序列
【发布时间】:2021-06-22 13:28:50
【问题描述】:

假设,我有这张桌子:

CREATE TABLE IF NOT EXISTS public.test
(
    "Id" smallint NOT NULL GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
    "Value" character varying(10)
);

然后我插入一些行:

INSERT INTO public.test ("Id", "Value") VALUES 
(1, 'Val1'),
(2, 'Val2'),
(3, 'Val3');

一切都很好。但现在我想插入另一行

INSERT INTO public.test ("Value") VALUES ('Val9');

我得到错误:duplicate key violates unique constraint

就是我怎么学的,因为pk-sequence不同步。但为什么? pg不自动更新序列有什么合理的原因吗?在单个 INSERT 之后效果很好,但在 BULK 之后不行吗?有什么办法可以避免这些手动更新?或者在每个小批量插入之后(如果有序列号),每个表的每个 pk 序列 correct 是标准的吗?

关于更多信息,我使用GENERATED BY DEFAULT,因为我想从 mysql 迁移数据库并且我想保留 ID。而且我希望在密钥方面具有很大的灵活性(类似于 mysql)。

但是我这里有什么不明白的地方?

是否可以在不知道具体名称的情况下自动更正序列?

抱歉,我想问的问题太多了。但是......我不明白这个概念。不胜感激。

【问题讨论】:

  • "单次插入后效果很好" - 我对此表示怀疑。是的,如果您覆盖默认值并忽略该序列,您总是必须在之后更正它。
  • 你是对的,我刚才又试了一次,和批量插入一样的错误。好的,至少一致的行为。谢谢。
  • 也许我的问题来自mysql。我有一个(真正有效的)默认序列(无需任何手动操作),并且也具有完全的灵活性。我可以更改一个 ID,但下次仍会插入一个正确的新 ID。

标签: postgresql sequence primary-key bulkinsert


【解决方案1】:

问题是GENERATED BY DEFAULT AS IDENTITY 中的BY DEFAULT。这意味着您可以覆盖自动生成的密钥,就像您的 INSERT 语句一样。

发生这种情况时,实现标识列的序列不会被修改。所以当你插入一行没有指定"Id"时,它会从1开始计数,这会导致冲突。

永远不要覆盖默认值。为确保这不会意外发生,请使用GENERATED ALWAYS AS IDENTITY

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2012-03-19
  • 1970-01-01
  • 2010-11-03
  • 1970-01-01
  • 2011-06-04
  • 2014-08-10
  • 1970-01-01
  • 2012-02-16
相关资源
最近更新 更多