途中でカラムの属性を変更したいときありますよね。
今回は、PostgreSQLでの変更方法を記載します。
前置き
-
AUTO_INCREMENT属性はMySQL用なので、PostgreSQLでは使用できない。
-
CREATE TABLE実行時に "serial" を型に指定すると、対応するシーケンスを自動生成してnextval()してくれるようになる。
-
integer型で定義したものを、後からALTER文でserial型に変えることはできない。
-
既存のカラムをserialに変更したい場合、手動でシーケンスを作って対処する。
手順
シーケンス作成
# create sequence test2_id1_seq;
CREATE SEQUENCE
# \d
List of relations
Schema | Name | Type | Owner
--------+---------------+----------+----------
public | test2 | table | postgres
public | test2_id1_seq | sequence | postgres
(8 rows)
id1カラムをserial型に変更
# alter table test2 alter id1 set default nextval('test2_id1_seq');
# \d test2
Table "public.test2"
Column | Type | Modifiers
--------+---------+-----------------------------------------------------
id1 | integer | not null default nextval('test2_id1_seq'::regclass)
id2 | integer | not null
id3 | integer | not null
Indexes:
"test2_pkey" PRIMARY KEY, btree (id1, id2, id3)
シーケンス(test2_id1_seq)を指定したテーブル(test2.id1)に関連づける。
# alter sequence test2_id1_seq owned by test2.id1;
ALTER SEQUENCE
# \d test2
Table "public.test2"
Column | Type | Modifiers
--------+---------+-----------------------------------------------------
id1 | integer | not null default nextval('test2_id1_seq'::regclass)
id2 | integer | not null
id3 | integer | not null
Indexes:
"test2_pkey" PRIMARY KEY, btree (id1, id2, id3)
シーケンスを100からはじめたい場合。
# select setval('test2_id1_seq',100);
setval
--------
100
(1 row)
INSERT前.
# select * from test2;
id1 | id2 | id3
-----+-----+-----
1 | 2 | 3
2 | 3 | 1
(2 rows)
INSERT後.
# insert into test2 (id2,id3) values('4','4');
INSERT 0 1
# select * from test2;
id1 | id2 | id3
-----+-----+-----
1 | 2 | 3
2 | 3 | 1
101 | 4 | 4
(3 rows)
その他検証
- 複数カラムにプライマリキー設定できるか?
→上記と同じ手順で設定変更。
# \d test2
Table "public.test2"
Column | Type | Modifiers
--------+---------+-----------------------------------------------------
id1 | integer | not null default nextval('test2_id1_seq'::regclass)
id2 | integer | not null default nextval('test2_id2_seq'::regclass)
id3 | integer | not null
Indexes:
"test2_pkey" PRIMARY KEY, btree (id1, id2, id3)
→OK
- ユニークでないカラム(id3)を途中からserial型に変更できるか?
# select * from test2;
id1 | id2 | id3
-----+------+-----
1 | 2 | 3
2 | 3 | 1
101 | 4 | 4
102 | 1001 | 33 ★
103 | 1002 | 44
105 | 1003 | 33 ★
(6 rows)
シーケンスを10000からはじめるように設定
# select setval('test2_id3_seq',10000);
setval
--------
10000
(1 row)
# insert into test2 (id4) values('11');
INSERT 0 1
# insert into test2 (id4) values('11');
INSERT 0 1
# select * from test2;
id1 | id2 | id3 | id4
-----+------+-------+-----
1 | 2 | 3 |
2 | 3 | 1 |
101 | 4 | 4 |
102 | 1001 | 33 | ★
103 | 1002 | 44 |
105 | 1003 | 33 | ★
106 | 1004 | 10001 | 11
107 | 1005 | 10002 | 11
108 | 1006 | 10003 | 11
(9 rows)
→重複しているカラムでも途中からserial型にできた!