【问题标题】:How to add an auto-incrementing primary key to an existing table, in PostgreSQL?如何在 PostgreSQL 中向现有表添加自动递增主键?
【发布时间】:2011-02-26 00:49:13
【问题描述】:

我有一个包含现有数据的表。有没有办法在不删除和重新创建表的情况下添加主键?

【问题讨论】:

    标签: postgresql primary-key auto-increment


    【解决方案1】:

    更新 - 感谢评论的人

    PostgreSQL 的现代版本

    假设您有一个名为 test1 的表,您想向其中添加一个自动递增的主键 id(代理)列。在 PostgreSQL 的最新版本中,以下命令应该足够了:

       ALTER TABLE test1 ADD COLUMN id SERIAL PRIMARY KEY;
    

    PostgreSQL 的旧版本

    在旧版本的 PostgreSQL(8.x 之前?)中,您必须完成所有繁琐的工作。以下命令序列应该可以解决问题:

      ALTER TABLE test1 ADD COLUMN id INTEGER;
      CREATE SEQUENCE test_id_seq OWNED BY test1.id;
      ALTER TABLE test ALTER COLUMN id SET DEFAULT nextval('test_id_seq');
      UPDATE test1 SET id = nextval('test_id_seq');
    

    同样,在最新版本的 Postgres 中,这大致相当于上面的单个命令。

    【讨论】:

    • 我正在使用 ORACLE,所以分享它可能对 ORACLE 的人有用 在 ORACLE 中:ALTER TABLE TEST1 ADD ID NUMBER;更新 TEST1 集 ID = TEST1_SEQ.NEXTVAL;更改表 TEST1 添加主键(ID);在执行 UPDATE 语句之前创建一个序列 TEST1_SEQ
    • 对于@resnyanskiy 的评论,即使表中有数据,这也将起作用。填充 ID 并且未设置空约束。整个答案可以替换为该评论中的行。
    • @EricWang 谢谢,埃里克,你是对的 - 我相信这在某些版本(几年)前不起作用,但我不确定。将答案变成了社区维基。
    • 那么大桌子呢?这些语句会锁定很长时间吗?
    • 使用ALTER TABLE <table> ADD COLUMN id SERIAL PRIMARY KEY时,如何将id指定为bigint
    【解决方案2】:
    ALTER TABLE test1 ADD COLUMN id SERIAL PRIMARY KEY;
    

    这就是你所需要的:

    1. 添加id
    2. 用从 1 到 count(*) 的序列填充它。
    3. 将其设置为主键/不为空。

    感谢@resnyanskiy,他在评论中给出了这个答案。

    【讨论】:

    • 这应该被标记为答案,并且答案应该属于@resnyanskiy
    • 我必须先删除 pkey 然后运行它。 ALTER TABLE <table> DROP CONSTRAINT <pkey_name>;
    【解决方案3】:

    要在 v10 中使用标识列,

    ALTER TABLE test 
    ADD COLUMN id { int | bigint | smallint}
    GENERATED { BY DEFAULT | ALWAYS } AS IDENTITY PRIMARY KEY;
    

    有关标识列的说明,请参阅https://blog.2ndquadrant.com/postgresql-10-identity-columns/

    有关 GENERATED BY DEFAULT 和 GENERATED ALWAYS 之间的区别,请参阅https://www.cybertec-postgresql.com/en/sequences-gains-and-pitfalls/

    要更改序列,请参阅https://popsql.io/learn-sql/postgresql/how-to-alter-sequence-in-postgresql/

    【讨论】:

    • 这个解决方案的问题是如果表已经包含行那么你会得到一个错误:SQL Error [23502]: ERROR: column "id" contains null values
    • @isapir:早期版本(第 10 和 10.1 页)中有一个错误会产生此错误。它已在 pg 10.2 中修复。详情在这里:dba.stackexchange.com/q/200143/3684
    【解决方案4】:

    我来到这里是因为我也在寻找类似的东西。在我的例子中,我将一组包含许多列的暂存表中的数据复制到一个表中,同时还将行 ID 分配给目标表。这是我使用的上述方法的变体。 我在目标表的末尾添加了序列列。这样我就不必在 Insert 语句中为其添加占位符。然后一个简单的选择 * 到目标表中自动填充此列。这是我在 PostgreSQL 9.6.4 上使用的两条 SQL 语句。

    ALTER TABLE target ADD COLUMN some_column SERIAL;
    INSERT INTO target SELECT * from source;
    

    【讨论】:

      【解决方案5】:

      ALTER TABLE test1 添加 id int8 NOT NULL 始终作为 IDENTITY 生成;

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-09-01
      • 2012-07-12
      • 2016-09-11
      • 2013-09-30
      • 2020-11-20
      • 1970-01-01
      相关资源
      最近更新 更多