テーブルPlayerと、character(7)の主キーplayerIDがあります。このテーブルにはすでにいくつかのレコードがあり、外部キーとしてplayerIDを持つ他のいくつかのテーブルもあり、それらのテーブルにもいくつかのレコードがすでにあります。
PlayerIDを自動インクリメントに設定するにはどうすればよいですか?しばらく読んだ後は最初からやった方がいいと思いますが、今は出来ないのでとにかく出来ますか?
たとえば、これを実行すると
ALTER TABLE player ADD COLUMN key_column BIGSERIAL PRIMARY KEY;
エラーを返します:
ERROR: multiple primary keys for table "player" are not allowed
既存のplayerIDを削除すると、それを参照する他のテーブルのレコードも削除されます。
既存のプライマリキーplayerIDを自動インクリメントに「変更」する方法はありますか?
私はそれを理解します: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
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 |
1つのテーブルに2つの主キーを含めることはできないと思います。playerIDデータ型はcharacter(7)であるため、自動インクリメントに変更できないと思います。
新しい主キーを追加できるようにするには、playerIDの主キー制約を削除する必要があると思います。
テーブルにすでにデータがあり、他のテーブルで外部キーとしてplayerIDを使用しているので、プレーヤーテーブルを複製し、これらの変更を2番目のテーブルでテストして、データの破損を防ぐことをお勧めします。
ただし、これをすべて試す前に、変更するテーブルを作成したのと同じdb-userを使用してこの変更を行っていることを確認してください。