テーブル構造をコピーして新しいテーブルを作成する(CREATE TABLE ... LIKE)

PostgreSQL ではテーブルを作成する時に LIKE を指定することで、作成済みのテーブルの構造をコピーした新しいテーブルを作成することができます。コピー元のテーブルで定義されているカラム名やデータ型や一部の制約などをコピーします。ここでは PostgreSQL でテーブル構造をコピーして新しいテーブルを作成する方法について解説します。

(Last modified: )

テーブル構造をコピーする

コピー元として指定したテーブルに含まれるカラムの情報などをコピーし新しいテーブルを作成します。書式は次のとおりです。

CREATE TABLE table_name (
  column_name data_type [, ... ]
  LIKE source_table
)

構造をコピーするテーブル( source_table )を指定してテーブルを作成します。コピー元で定義されているすべてのカラムの名前とデータ型、そして一部の制約をコピーしたテーブルが作成されます。コピー先にテーブルにはテーブル独自のカラムを追加で定義することもできます。

テーブルを継承する INHERITS 句を指定した場合と似ていますが、テーブルを継承した場合は親テーブルと子テーブルのカラムが連動しており、また親テーブルからデータを取得した時に子テーブルのデータも含めて取得されますが、テービル構造をコピーする LIKE 句の場合はコピー元とコピー先はまったく別のテーブルとなります。( INHERITS 句について詳しくは「テーブルを継承して新しいテーブルを作成する(CREATE TABLE ... INHERITS)」を参照されてください)。

-- --

それでは実際に試してみます。 mydb データベースの myschema スキーマにコピー元となる次のようなテーブルを作成しました。

create table myschema.customer (
  name varchar(10), 
  address varchar(10) NOT NULL
);

テーブル構造をコピーする(1)

作成したテーブルには次のようなデータを追加しておきました。

insert into myschema.customer values
  ('Yamada', 'Tokyo'), 
  ('Honda', 'Kyoto'), 
  ('Watanabe', 'Nara'),
  ('Asada', 'Osaka');

テーブル構造をコピーする(2)

次に先ほど作成した customer テーブルのテーブル構造をコピーして新しいテーブルを作成します。 mydb データベースの myschema スキーマに次のようなテーブルを作成しました。

create table myschema.feecustomer (
  billingdate date, 
  like myschema.customer
);

テーブル構造をコピーする(3)

psql メタコマンドの \d コマンドを使って作成したテーブルのカラムに関する情報を表示してみます。

\d myschema.feecustomer

テーブル構造をコピーする(4)

feecustomer テーブルでは定義したカラム billingdate カラムに加えて、テーブル定義をコピーした customer テーブルで定義されたカラムがすべて含まれます。コピーされたものはカラム名とデータ型に加えて NOT NULL制約もコピーされています。

なおあくまでテーブル構造だけがコピーされてデータはコピーされません。作成した直後の myschema.feecustomer テーブルに対して SELECT コマンドを実行してみます。

select * from myschema.feecustomer;

テーブル構造をコピーする(5)

データが一つも含まれていないことが確認できました。

制約も含めてコピーする

CREATE TABLE ... LIKE コマンドを使用する場合、すでに試したように NOT NULL 制約はデフォルトでコピーされます。その他の制約についてはオプションで指定することで制約をコピーすることができます。

CREATE TABLE table_name (
  column_name data_type [, ... ]
  LIKE source_table [ like_option ... ]
) 

オプションに指定できる値は次の通りです。複数指定する場合は続けて記述してください。

INCLUDING DEFAULTS
DEFAULT 制約をコピーします

INCLUDING IDENTITY
カラムへの IDENTITY の指定がコピーされます
カラムに割り当てられるシーケンスはコピー元とコピー先で異なります

INCLUDING CONSTRAINTS
CHECK 制約がコピーされます

INCLUDING INDEXES
PRIMARY KEY 、 UNIQUE 、 EXCLUDE の各制約がコピーされます

INCLUDING COMMENTS
カラム、制約、インデックスに関するコメントがコピーされます

INCLUDING STATISTICS
拡張統計情報がコピーされます

INCLUDING STORAG
カラム定義に関する STORAGE 設定がコピーされます

INCLUDING ALL
全てのオプションを指定したのと同じです

簡単なテストをするために次のようなテーブルを作成しました。

create table sourcetbl (
  num1 integer primary key,
  num2 integer default 5,
  num3 integer check (num3 != 0)
);

続いて先ほど作成したテーブル構造をコピーし新しいテーブルを次のように作成します。今回はインデックスに関する制約( PRIMARY KEY 制約や UNIQUE 制約)、および DEFAULT 制約についてはコピーするように設定しています。

create table destinationtbl (
  like sourcetbl including indexes including defaults
);

テーブルを作成後、 psql メタコマンドの \d コマンドを使ってテーブルに含まれるカラムの情報を取得してみます。

\d destinationtbl

制約も含めてコピーする(1)

カラム名やデータ型の他に PRIMARY KEY に関する制約と DEAFULT 制約がコピーされているのが確認できました。今回オプションで指定していない CHECK 制約はコピーされていません。

複数のテーブルのテーブル構造をコピーする

テーブル構造のコピーは複数のテーブルから行うことができます。コピー先のテーブルではコピー元のそれぞれのテーブルで定義されているすべてのカラムを持つことになります。

CREATE TABLE table_name (
  column_name data_type [, ... ]
  LIKE source_table1 [ like_option ... ],
  LIKE source_table2 [ like_option ... ]
) 

複数のテーブルから行う場合は、コピー元のテーブルで同じ名前のカラムが存在していた場合はエラーとなりますので注意してください。

簡単なテストを行うために次のようなテーブルを 2 つ作成しました。

create table sourcetbl_a (
  num_a integer not null,
  str_a varchar(10)
);
create table sourcetbl_b (
  num_b integer,
  str_b char(8)
);

次に 2 つのテーブルの構造をコピーしたテーブルを作成します。

create table childtbl (
  like sourcetbl_a,
  like sourcetbl_b
);

複数のテーブルのテーブル構造をコピーする(1)

テーブルを作成後、 psql メタコマンドの \d コマンドを使ってテーブルに含まれるカラムの情報を取得してみます。

\d childtbl

複数のテーブルのテーブル構造をコピーする(2)

2 つのテーブルで定義されていたカラムをすべてコピーして新しいテーブルが作成されていることが確認できました。

-- --

テーブル構造をコピーして新しいテーブルを作成する方法について解説しました。

( Written by Tatsuo Ikura )

プロフィール画像

著者 / TATSUO IKURA

これから IT 関連の知識を学ばれる方を対象に、色々な言語でのプログラミング方法や関連する技術、開発環境構築などに関する解説サイトを運営しています。