web-dev-qa-db-ja.com

PostgreSQLで自動インクリメントの主キーを既存のテーブルに追加する方法は?

既存のデータを含むテーブルがあります。テーブルを削除して再作成せずに主キーを追加する方法はありますか?

167
xRobot

更新-コメントしてくれた人に感謝

PostgreSQLの最新バージョン

test1という名前のテーブルがあり、そこに自動インクリメントの主キーid(代理)列を追加するとします。 PostgreSQLの最近のバージョンでは、次のコマンドで十分です。

   ALTER TABLE test1 ADD COLUMN id SERIAL PRIMARY KEY;

PostgreSQLの古いバージョン

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の最近のバージョンでは、これは上記の単一のコマンドとほぼ同等です。

310
leonbloy
ALTER TABLE test1 ADD COLUMN id SERIAL PRIMARY KEY;

これはあなたがする必要があるすべてです:

  1. id列を追加します
  2. 1からcount(*)までのシーケンスを入力します。
  3. 主キーとして設定する/ null以外。

この回答をコメントで提供した@resnyanskiyにクレジットが与えられます。

47
Synesso

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/ を参照してください。

6
jhoanna

私もそのようなものを探していたので、私はここに着陸しました。私の場合、行IDをターゲットテーブルに割り当てながら、多くの列を持つステージングテーブルのセットから1つのテーブルにデータをコピーしていました。以下は、私が使用した上記のアプローチの変形です。ターゲットテーブルの最後にシリアル列を追加しました。そうすれば、Insertステートメントにプレースホルダーを置く必要がなくなります。次に、ターゲットテーブルへの単純なselect *がこの列に自動的に入力されました。 PostgreSQL 9.6.4で使用した2つのSQLステートメントを次に示します。

ALTER TABLE target ADD COLUMN some_column SERIAL;
INSERT INTO target SELECT * from source;
2
Dean Sha