我有一个现有数据表。是否有一种方法可以在不删除和重新创建表的情况下添加主键?
(更新-感谢那些评论的人)
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;
这就是你需要做的:
添加id列 用从1到count(*)的序列填充它。 设置为主键/非空。
感谢@resnyanskiy,他在评论中给出了这个答案。
I landed here because I was looking for something like that too. In my case, I was copying the data from a set of staging tables with many columns into one table while also assigning row ids to the target table. Here is a variant of the above approaches that I used. I added the serial column at the end of my target table. That way I don't have to have a placeholder for it in the Insert statement. Then a simple select * into the target table auto populated this column. Here are the two SQL statements that I used on PostgreSQL 9.6.4.
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/。
推荐文章
- 查询JSON类型内的数组元素
- 获得PostgreSQL数据库中当前连接数的正确查询
- 纬度和经度的数据类型是什么?
- 如何在PostgreSQL中临时禁用触发器?
- 输入文件似乎是一个文本格式转储。请使用psql
- 使用LIMIT/OFFSET运行查询,还可以获得总行数
- 当恢复sql时,psql无效命令\N
- 货币应该使用哪种数据类型?
- 如何添加列,如果不存在PostgreSQL?
- 如何在Postgres中获得两个字段的MIN() ?
- 截断Postgres数据库中的所有表
- 如何连接列在Postgres选择?
- 将varchar字段的类型更改为整数:"不能自动转换为整数类型"
- PostgreSQL可以索引数组列吗?
- INT和VARCHAR主键之间有真正的性能差异吗?