如何添加一个自动递增的主键到现有的表,在PostgreSQL?

我有一个现有数据表。是否有一种方法可以在不删除和重新创建表的情况下添加主键?

265145 次浏览

(更新-感谢那些评论的人)

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 test1 ALTER COLUMN id SET DEFAULT nextval('test_id_seq');
UPDATE test1 SET id = nextval('test_id_seq');

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

ALTER TABLE test1 ADD COLUMN id SERIAL PRIMARY KEY;

这就是你需要做的:

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

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

我降落在这里,因为我也在寻找类似的东西。在我的例子中,我将数据从一组具有许多列的staging表复制到一个表中,同时将行id分配给目标表。下面是我使用的上述方法的一个变体。 我在目标表的末尾添加了串行列。这样我就不必在Insert语句中为它设置占位符。然后一个简单的select *进入目标表自动填充此列。下面是我在PostgreSQL 9.6.4上使用的两条SQL语句。< / p >
ALTER TABLE target ADD COLUMN some_column SERIAL;
INSERT INTO target SELECT * from source;

要在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/

ALTER TABLE test1:添加id int8为NULL