Postgres 10 以降
Postgres 10 では、SQL 標準に準拠したIDENTITY
列が導入されました (マイナーな拡張機能付き)。テーブルの ID 列は次のようになります。
id integer PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY
マニュアルの構文。従来の列
の代わりにこれを使用すると、シーケンスに関する問題が回避されます。列は、仕様が でコピーされた場合でも、排他的な専用シーケンスを自動的に使用します。マニュアル:serial
IDENTITY
LIKE
コピーされた列定義の ID 指定は、INCLUDING IDENTITY
が指定されている場合にのみコピーされます。古いテーブルに関連付けられたシーケンスとは別に、新しいテーブルの ID 列ごとに新しいシーケンスが作成されます。
と:
INCLUDING ALL
の省略形ですINCLUDING DEFAULTS INCLUDING IDENTITY INCLUDING CONSTRAINTS INCLUDING INDEXES INCLUDING STORAGE INCLUDING COMMENTS
。
解決策はより簡単になりました:
CREATE TEMP TABLE t_mytable (LIKE mytable INCLUDING ALL);
INSERT INTO t_mytable TABLE mytable;
SELECT setval(pg_get_serial_sequence('t_mytable', 'id'), max(id)) FROM tbl;
setval()
示されているように、シーケンスの現在の値を設定するために引き続き使用できます。シングルSELECT
はトリックを行います。pg_get_serial_sequence()
] 6シーケンスの名前を取得します。
デシベル<>ここでフィドル
関連している:
元の(古い)回答
データベース ダンプまたはpgAdmin (データベース オブジェクト作成スクリプトをリバース エンジニアリングする)などの GUI から create スクリプトを取得し、同一のコピーを作成して (serial
列のシーケンスを個別に)、次のコマンドを実行します。
INSERT INTO new_tbl
SELECT * FROM old_tbl;
両方のテーブルが同じスキーマに存在する場合、コピーを 100% 同一にすることはできません。明らかに、テーブル名は異なる必要があります。インデックス名も競合します。同じシーケンスからシリアル番号を取得することも、おそらく最善の利益にはなりません。したがって、(少なくとも) 名前を調整する必要があります。
コピーを別のスキーマに配置すると、これらの競合がすべて回避されます。デモのように通常のテーブルから一時テーブルを作成しますが、一時テーブルは独自の一時スキーマに存在するため、自動的に作成されます。
または、DDL コードを直接コピーするための Francisco の回答をご覧ください。