Изменить первичный ключ на автоматическое увеличение

У меня есть таблица Player и первичный ключ playerID, который является символом (7). У меня уже есть некоторые записи в этой таблице, а также есть некоторые другие таблицы с playerID в качестве внешнего ключа, и в этих таблицах также уже есть некоторые записи.

Как настроить автоматическое увеличение идентификатора игрока? Почитав некоторое время, я подумал, что должен был сделать это с самого начала, но, поскольку я не могу этого сделать сейчас, могу ли я это сделать?

Например, когда я запускаю это

ALTER TABLE player ADD COLUMN key_column BIGSERIAL PRIMARY KEY;

он возвращает ошибку:

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

и если я удалю существующий идентификатор игрока, записи в других таблицах, которые ссылаются на него, также будут удалены.

Есть ли способ «изменить» существующий первичный ключ playerID на автоматическое увеличение?


person Chin    schedule 01.04.2013    source источник


Ответы (4)


Я разобрался: просто добавьте к 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
person Chin    schedule 01.04.2013
comment
Я использовал немного более надежный запрос для определения максимума: select setval('player_id_seq', (select max(player_id_seq) from player) + 1); - person aqteifan; 12.01.2020

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 | 
person wildplasser    schedule 01.04.2013

Я не думаю, что у вас может быть 2 первичных ключа в одной таблице, и, поскольку тип данных playerID - символ (7), я не думаю, что вы можете изменить его на автоматическое увеличение.

Поэтому я считаю, что вам придется удалить ограничение первичного ключа для playerID, если вы хотите иметь возможность добавить новый первичный ключ.

Поскольку у вас уже есть данные в вашей таблице, и вы используете playerID в качестве внешнего ключа в других таблицах, я бы посоветовал вам продублировать таблицу игроков и проверить эти изменения на второй таблице, чтобы не повредить ваши данные.

Но прежде чем попробовать все это, убедитесь, что вы пытаетесь внести эти изменения, используя того же пользователя базы данных, который создал таблицы, которые вы изменяете.

person Ferox    schedule 01.04.2013

Следующий код установит автоматическое увеличение существующего столбца в PGSQL:

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

                                      
person Claudio Melo    schedule 26.06.2020
comment
Пожалуйста, правильно отформатируйте код. нажмите здесь, чтобы узнать, как это сделать. - person Богдан Опир; 26.06.2020
comment
Извините, что написал это в комментариях, @БогданОпир, но я не знаю другого пути. Ваш комментарий адресован оригинальному ответу? Или код все еще отформатирован неправильно после того, как я его отредактировал? - person Sigfried; 27.06.2020
comment
@Sigfried Это было адресовано ОП. Вам больше не нужно его менять. Тем не менее, по-прежнему предпочтительнее использовать тройные обратные кавычки. - person Богдан Опир; 27.06.2020
comment
Спасибо, @БогданОпир. Я заметил опечатку в ответе и просто исправил ее, и, поскольку при редактировании есть странный минимум 6 символов, я попытался переключиться на тройные обратные кавычки, но затем я потерял окраску синтаксиса. Я добавил {lang=sql} после верхнего обратного апострофа (и указал язык), но это не помогло. На странице, на которую вы ссылаетесь, не упоминаются тройные обратные кавычки. - person Sigfried; 27.06.2020
comment
@Sigfried Обновляет подсветку синтаксиса предварительного просмотра только раз в 10 секунд (по умолчанию). - person Богдан Опир; 27.06.2020