将主键更改为自动递增

Posted

技术标签:

【中文标题】将主键更改为自动递增【英文标题】:Change primary key to auto increment 【发布时间】:2013-03-22 19:47:00 【问题描述】:

我有一个表 Player,主键 playerID 是 character(7)。我这个表里已经有一些记录了,还有一些其他的表有playerID作为外键,这些表也已经有一些记录了。

如何将 playerID 设置为自动递增?看了一会觉得应该从一开始就做这个,但是既然现在做不到,那有没有可以做的呢?

例如,当我运行这个时

ALTER TABLE player ADD COLUMN key_column BIGSERIAL PRIMARY KEY;

它返回一个错误:

ERROR: multiple primary keys for table "player" are not allowed

如果我删除现有的 playerID,其他表中引用它的记录也将被删除。

有没有办法将现有的主键 playerID“更改”为自动递增?

【问题讨论】:

【参考方案1】:

我想通了:只需在 playerID 中添加一个自动递增的默认值即可:

create sequence player_id_seq;
alter table player alter playerid set default nextval('player_id_seq');
Select setval('player_id_seq', 2000051 ); --set to the highest current value of playerID

【讨论】:

我使用了更强大的查询来确定最大值:select setval('player_id_seq', (select max(player_id_seq) from player) + 1);【参考方案2】:
DROP SCHEMA tmp CASCADE;
CREATE SCHEMA tmp ;
SET search_path=tmp;

   -- create som data to play with
CREATE TABLE bagger
        ( player_id CHAR(6)
        , tralala varchar
        );

  -- populate the table
INSERT INTO bagger(player_id,tralala)
SELECT gs::text, 'zzz_' || gs::text
FROM generate_series(1,10) gs
        ;

SELECT * FROM bagger;

  --
  -- create the sequence, change the datatype and bind it to the sequence
  --
CREATE SEQUENCE player_id_seq;
ALTER TABLE bagger
        ALTER COLUMN player_id TYPE INTEGER USING player_id::integer
        , ALTER COLUMN player_id SET NOT NULL
        , ALTER COLUMN player_id SET DEFAULT nextval('player_id_seq')
        ;
ALTER SEQUENCE player_id_seq
        OWNED BY bagger.player_id
        ;
   --
   -- reset the sequence to containe the maximum occuring player_id in the table
   --
SELECT setval('player_id_seq', mx.mx)
FROM (SELECT MAX(player_id) AS mx FROM bagger) mx
        ;
SELECT * FROM bagger;
\d bagger

输出:

DROP SCHEMA
CREATE SCHEMA
SET
CREATE TABLE
INSERT 0 10
 player_id | tralala 
-----------+---------
 1         | zzz_1
 2         | zzz_2
 3         | zzz_3
 4         | zzz_4
 5         | zzz_5
 6         | zzz_6
 7         | zzz_7
 8         | zzz_8
 9         | zzz_9
 10        | zzz_10
(10 rows)

CREATE SEQUENCE
ALTER TABLE

 setval 
--------
     10
(1 row)

 player_id | tralala 
-----------+---------
         1 | zzz_1
         2 | zzz_2
         3 | zzz_3
         4 | zzz_4
         5 | zzz_5
         6 | zzz_6
         7 | zzz_7
         8 | zzz_8
         9 | zzz_9
        10 | zzz_10
(10 rows)

                                 Table "tmp.bagger"
  Column   |       Type        |                      Modifiers                      
-----------+-------------------+-----------------------------------------------------
 player_id | integer           | not null default nextval('player_id_seq'::regclass)
 tralala   | character varying | 

【讨论】:

【参考方案3】:

我不认为你可以在一个表中有 2 个主键,并且因为 playerID 数据类型是字符(7)我不认为你可以将其更改为自动递增。

所以我相信如果您希望能够添加新的主键,则必须删除 playerID 上的主键约束。

由于您的表中已有数据,并且您在其他表中使用 playerID 作为外键,我建议您复制您的播放器表并在第二个表上测试这些更改以避免损坏您的数据。

但在您尝试所有这些之前,请确保您尝试使用创建要更改的表的同一 db-user 进行更改

【讨论】:

【参考方案4】:

以下代码将自动递增设置为 PGSQL 中的现有列:

ALTER TABLE schema.table ALTER COLUMN id 
  SET DEFAULT nextval('schema.table_id_seq'::regclass);

                                      

【讨论】:

请正确格式化您的代码,click here to learn how。 很抱歉将其放入 cmets,@БогданОпир,但我不知道其他方式。您的评论是否针对原始答案?还是我编辑后代码格式仍然错误? @Sigfried 它是针对 OP 的。你不需要再改变它了。但是,仍然首选使用三个反引号。 谢谢,@БогданОпир。我注意到答案中有一个错字并修复了它,并且由于编辑时最少有一个奇怪的 6 个字符,我尝试切换到三个反引号,但后来我失去了语法着色。 Iried lang=sql 在顶部反引号(和语言拼写)之后,但这没有帮助。您链接的页面没有提到三个反引号。 @Sigfried 它只更新预览语法高亮一次 10 秒(默认)

以上是关于将主键更改为自动递增的主要内容,如果未能解决你的问题,请参考以下文章

将主键更改为复合主键

将整数类型的所有主键更改为 bigint,包括引用

MySQL:为啥将主键与不​​使用索引的随机生成的数字进行比较?

SQL:插入期间自动递增值

防止自动递增整数主键?

在oracle 怎样设置自动递增的的字段,也就是设置自动递增的ID 主键