PRIMARY KEY制約(主キー/プライマリキーを設定する)

テーブルを作成する時にカラムに対して PRIMARY KEY 制約をつけると、カラムに重複した値を格納することができなくなります。 UNIQUE 制約と似ていますが PRIMARY KEY 制約が設定されたカラムには NULL を格納することができず、また PRIMARY KEY 制約はテーブルに一つしか設定することができません。ここでは PostgreSQL における PRIMARY KEY 制約の使い方について解説します。

(Last modified: )

PRIMARY KEY制約の使い方

テーブルを作成するとき、カラムに対して PRIMARY KEY 制約を設定すると、そのカラムがテーブルにおける主キー/プライマリーキーとなります。 PRIMARY KEY 制約が設定されたカラムには重複した値を追加することができず NULL も格納できません。書式は次のとおりです。

CREATE TABLE [ IF NOT EXISTS ] table_name (
  column_name data_type PRIMARY KEY [, ... ]
)

また PRIMARY KEY 制約はカラム毎ではなくテーブルに対して設定することもできます。

CREATE TABLE [ IF NOT EXISTS ] table_name (
  column_name1 data_type1, 
  column_name2 data_type2,
  [... ,]
  PRIMARY KEY ( column_name [, ... ] )
)

カラムの定義と分けて記述したい場合や、複数のカラムの組み合わせに対して PRIMARY KEY 制約を設定したい場合などに使用します。

-- --

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

create table myschema.employee (
  name varchar(10) primary key, 
  department varchar(10)
);

PRIMARY KEY制約の使い方(1)

name カラムに PRIMARY KEY 制約を設定していますので name カラムには重複した値を格納することはできません。

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

\d myschema.employee

PRIMARY KEY制約の使い方(2)

name カラムの「Null 値を許容」の列の値に not null と表示されています。またテーブルに PRIMARY KEY 制約を設定すると自動的にインデックスが作成されます。欄外に作成されたインデックスに関するインデックスの名前や対象となっているカラムに関する情報が表示されています。

自動で作成されたインデックスに関する情報を取得するには、 psql メタコマンドの \d コマンドを使います。引数に先ほど \d コマンドで表示されたインデックス名を指定して次のように実行してください。

\d myschema.employee_pkey

PRIMARY KEY制約の使い方(3)

作成されたインデックスに関する情報が表示されました。

それではテーブルにデータを追加してみます。最初に次のようなデータを 3 つ追加しました。

insert into myschema.employee values
  ('Yamada', 'Sales'), 
  ('Kondo', 'Legal'), 
  ('Kurita', 'Marketing');

PRIMARY KEY制約の使い方(4)

これらのデータは name カラムの値が重複していませんので問題なく追加できます。

次に name カラムの値として既にテーブルに格納されている値と同じ値を指定してデータを追加してみます。

insert into myschema.employee values ('Kondo', 'Customer');

PRIMARY KEY制約の使い方(5)

PRIMARY KEY 制約が設定されている name カラムに重複した値を追加しようとしたので ERROR: 重複キーが一意性制約"employee_pkey"に違反しています というエラーが表示されてデータの追加に失敗しました。

なお PRIMARY KEY 制約を設定したカラムは自動的に NOT NULL 制約も設定されるため、 PRIMARY KEY 制約が設定されているカラムに NULL が格納されるようなデータは追加することができません。実際に試してみます。

insert into myschema.employee values (NULL, 'General');

PRIMARY KEY制約の使い方(5)

ERROR: 列"name"内のNULL値はNOT NULL制約違反です とエラーが表示されてデータの追加に失敗しました。

複数のカラムの組み合わせに対してPRIMARY KEY制約を設定する

PRIMARY KEY 制約は複数のカラムの組み合わせに対して設定することもできます。この場合、それぞれのカラムには重複した値が格納されていてもエラーとはなりませんが、対象のすべてのカラムの値の組み合わせが一致するデータは追加することができません。

複数のカラムの組み合わせに PRIMARY KEY 制約を設定するにはテーブルに対する PRIMARY KEY 制約の書式を使用します。

CREATE TABLE [ IF NOT EXISTS ] table_name (
  column_name1 data_type1, 
  column_name2 data_type2,
  [... ,]
  PRIMARY KEY ( column_name [, ... ] )
)

-- --

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

create table myschema.employee (
  id integer, name varchar(10), 
  department varchar(10), 
  primary key(name, department)
);

複数のカラムの組み合わせに対してPRIMARY KEY制約を設定する(1)

name カラムと department カラムの組み合わせに PRIMARY KEY 制約を設定していますので name カラムと department カラムの組み合わせが重複したデータは格納することはできません。

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

\d myschema.employee

複数のカラムの組み合わせに対してPRIMARY KEY制約を設定する(2)

name カラムおよび department カラムの「Null 値を許容」の列の値に not null と表示されています。またテーブルに PRIMARY KEY 制約を設定すると自動的にインデックスが作成されます。欄外に作成されたインデックスに関するインデックスの名前や対象となっているカラムに関する情報が表示されています。

自動で作成されたインデックスに関する情報を取得するには、 psql メタコマンドの \d コマンドを使います。引数に先ほど \d コマンドで表示されたインデックス名を指定して次のように実行してください。

\d myschema.employee_pkey

複数のカラムの組み合わせに対してPRIMARY KEY制約を設定する(3)

作成されたインデックスに関する情報が表示されました。

それではテーブルにデータを追加してみます。最初に次のようなデータを 3 つ追加しました。

insert into myschema.employee values
  (1, 'Yamada', 'Sales'), 
  (2, 'Kondo', 'Legal'), 
  (3, 'Kurita', 'Sales');

複数のカラムの組み合わせに対してPRIMARY KEY制約を設定する(4)

department カラムの値だけをみると重複したデータも追加されていますが、 name カラムと department カラムの組み合わせが同じデータはありませんので PRIMARY KEY 制約でエラーとなることはありません。

次に name カラムと department カラムの組み合わせが既にテーブルに格納されている値と同じ値を指定してデータを追加してみます。

insert into myschema.employee values (4, 'Kondo', 'Legal');

複数のカラムの組み合わせに対してPRIMARY KEY制約を設定する(5)

PRIMARY KEY 制約が設定されている name カラムと department カラムの組み合わせに重複した値を追加しようとしたので ERROR: 重複キーが一意性制約"employee_pkey"に違反しています というエラーが表示されてデータの追加に失敗しました。

なお PRIMARY KEY 制約を設定したカラムは自動的に NOT NULL 制約も設定されるため、 PRIMARY KEY 制約が設定されているカラムに NULL が格納されるようなデータは追加することができません。実際に試してみます。

insert into myschema.employee values (5, NULL, 'General');

複数のカラムの組み合わせに対してPRIMARY KEY制約を設定する(5)

ERROR: 列"name"内のNULL値はNOT NULL制約違反です とエラーが表示されてデータの追加に失敗しました。

-- --

PRIMARY KEY 制約の使い方について解説しました。

( Written by Tatsuo Ikura )

プロフィール画像

著者 / TATSUO IKURA

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