既存のデータを含むテーブルがあります。テーブルを削除して再作成せずに主キーを追加する方法はありますか?
(更新-コメントしてくれた人に感謝)
test1
という名前のテーブルがあり、そこに自動インクリメントの主キーid
(代理)列を追加するとします。 PostgreSQLの最近のバージョンでは、次のコマンドで十分です。
ALTER TABLE test1 ADD COLUMN id SERIAL PRIMARY KEY;
PostgreSQLの古いバージョン(8.xより前?)では、すべての汚い仕事をしなければなりませんでした。次の一連のコマンドでトリックを行う必要があります。
ALTER TABLE test1 ADD COLUMN id INTEGER;
CREATE SEQUENCE test_id_seq OWNED BY test1.id;
ALTER TABLE test 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
列を追加しますこの回答をコメントで提供した@resnyanskiyにクレジットが与えられます。
V10でID列を使用するには、
ALTER TABLE test
ADD COLUMN id { int | bigint | smallint}
GENERATED { BY DEFAULT | ALWAYS } AS IDENTITY PRIMARY KEY;
ID列の説明については、 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/ を参照してください。
私もそのようなものを探していたので、私はここに着陸しました。私の場合、行IDをターゲットテーブルに割り当てながら、多くの列を持つステージングテーブルのセットから1つのテーブルにデータをコピーしていました。以下は、私が使用した上記のアプローチの変形です。ターゲットテーブルの最後にシリアル列を追加しました。そうすれば、Insertステートメントにプレースホルダーを置く必要がなくなります。次に、ターゲットテーブルへの単純なselect *がこの列に自動的に入力されました。 PostgreSQL 9.6.4で使用した2つのSQLステートメントを次に示します。
ALTER TABLE target ADD COLUMN some_column SERIAL;
INSERT INTO target SELECT * from source;