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

プライマリーキー(主キー)とは作成したテーブルの中の1つまたは複数のカラムの組み合わせに対して設定するもので、テーブルに格納されているデータをに格納されているデータを識別するための目印のようなものです。ここではプライマリキーについての簡単な解説と、 MySQL のテーブルでプライマリキーを設定して利用する方法について解説します。

テーブルを作成したあとにプライマリーキーを作成したり、作成したプライマリーキーを削除する方法については「インデックスの作成」を参照してください。

(Last modified: )

プライマリーキー(主キー)とは

最初にプライマリーキーについて簡単にご説明します。テーブルには多くのデータが含まれており、 1 つ 1 つのデータには複数のカラムの値が格納されています。格納されたすべてのデータの中から 1 つのデータを特定したいときに、 1 つまたは複数のカラムの値を検索してデータを特定しますが、その時に最も適したカラムに設定されるのがプライマリーキーです。

カラムにプライマリーキー制約を設定すると、カラムには他のデータの値を重複することのない値しか格納することができなくなります。また NULL も格納することができません。その結果、プライマリーキー制約が設定されたカラムの値を検索することで、テーブルの中でただ一つのデータを特定することができます。

例えば社員テーブルのようなテーブルで考えてみます。

プライマリーキー(主キー)とは(1)

社員テーブルの場合、部署や性別のデータは複数のデータで同じ値が格納されてしまいますし、名前についても偶然同じ名前の人がいる可能性があります。

プライマリーキー(主キー)とは(2)

それに対して社員番号は社員一人一人に別々の番号が割り当てられています。このように他のデータと値が重複することがないカラムに対してプライマリキー制約は設定することができます。

プライマリーキー(主キー)とは(3)

プライマリーキーが設定された社員番号を検索すれば、必ずただ一人の社員を特定することができます。

プライマリーキー(主キー)とは(4)

プライマリーキーが設定されたカラムに対しては自動的にインデックスが作成されます。インデックスとは指定したカラムのデータを取り出して検索用にまとめたもので、インデックスを作成しておくとテーブルのデータを高速に検索できます。インデックスはテーブルの中で複数作成することができますが、その中でも重複する値が格納されておらず特に重要なカラムに対してプライマリーキーが設定されます。

プライマリーキーと似た制約にユニーク制約というものがあります。ユニーク制約が設定されたカラムも重複した値を格納することができませんが、 NULL を格納することができ、またテーブルに複数作成できるという点が異なります。ユニーク制約については「UNIQUE制約(ユニーク制約を設定する)」で解説します。

PRIMARY KEY制約の使い方

カラムに対して PRIMARY KEY 制約を設定するには次の書式を使用します。

CREATE TABLE db_name.tbl_name
  (col_name data_type NOT NULL PRIMARY KEY, ...)

また複数のカラムの組み合わせに対して PRIMARY KEY 制約を設定する場合はこの書式も利用できます。これはあとで解説します。

CREATE TABLE db_name.tbl_name
  (col_name data_type NOT NULL, ..., PRIMARY KEY(col_name, ...))

カラムのデータ型のあとに PRIMARY KEY を記述します。 PRIMARY KEY はテーブルごとに 1 つしか設定することができず、また設定するカラムには NOT NULL 制約を合わせて設定する必要があります。明示的に NOT NULL 制約を設定しなくてもエラーとはなりませんが、自動的に NOT NULL 制約が設定されます。(NOT NULL 制約については「NOT NULL制約(カラムにNULLの格納を許可するかどうか)」を参照してください)。

PRIMARY KEY 制約が設定されたカラムには重複した値を格納できなくなります。

では実際に試してみます。次のようなテーブルを作成します。

create table staff(id int not null primary key, name varchar(10));

PRIMARY KEY制約の使い方(1)

作成したテーブルのカラム情報を取得してみます。

show columns from staff;

PRIMARY KEY制約の使い方(2)

PRIMARY KEY 制約が設定された id カラムには自動でインデックスが作成されており、Key カラムの値に PRI と設定されています。

また PRIMARY KEY 制約を設定すると自動的にインデックスが作成されます。作成されたインデックスについて SHOW INDEX文を使って確認してみます。

show index from staff\G

PRIMARY KEY制約の使い方(3)

作成されたインデックスの名前は PRIMARY で、Non_unique が 0 となっているので重複した値を格納することができません。

-- --

テーブルにデータを追加します。最初に問題のないデータを追加してみます。

insert into staff values(1, 'Yamada');
insert into staff values(4, 'Suzuki');

PRIMARY KEY制約の使い方(4)

PRIMARY KEY 制約を設定したカラムの値が既存のデータの値と重複しておらずまた NULL でもないので問題なくデータが格納できました。

次に id カラムの値が既存のデータの値と同じデータを追加してみます。

insert into staff values(4, 'Honda');

PRIMARY KEY制約の使い方(5)

Duplicate entry '値' for key 'PRIMARY' というエラーが発生しました。 id カラムには PRIMARY KEY 制約が付いていますので、既存の値と同じ値を格納しようとするとエラーになります。

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

PRIMARY KEY はテーブルに 1 つしか設定することができませんが、対象となるカラムは 1 つだけではなく 複数のカラムの組み合わせに対して設定することができます。例えば 2 つのカラムの組み合わせに対して設定した場合、 2 つのカラムに格納されている値の組み合わせが他のデータと重複することはできなくなります。

社員テーブルを例にしてみると、入社年度と社員番号のカラムは単独のカラムの値としてみるとそれぞれ重複した値が格納されていますが、 2 つのカラムの組み合わせは重複していません。このような 2 つのカラムの組み合わせに対して PRIMARY KEY 制約を設定することができます。

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

複数のカラムを対象とした PRIMARY KEY 制約を設定するには次の書式を使用します。

CREATE TABLE db_name.tbl_name
  (col_name1 data_type1 NOT NULL, col_name2 data_type2 NOT NULL, ..., 
   PRIMARY KEY(col_name1, col_name2, ...))

では実際に試してみます。次のようなテーブルを作成します。

create table staff(joiny int not null, id int not null, name varchar(10), primary key(joiny, id));

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

作成したテーブルのカラム情報を取得してみます。

show columns from staff;

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

PRIMARY KEY が設定された joiny カラムと id カラムには自動でインデックスが作成されており、Key カラムの値をみていただくと PRI が格納されています。

また PRIMARY KEY 制約を設定すると自動的にインデックスが作成されます。作成されたインデックスについて SHOW INDEX文を使って確認してみます。

show index from staff\G

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

インデックスは 2 つ作成されていますが、どちらもインデックスの名前は PRIMARY です。違いは 1 つめのインデックスは Column_name の値が joiny なのに対して、 2 つめのインデックスは Column_name の値が id になっています。

-- --

テーブルにデータを追加します。最初に問題のないデータを追加してみます。

insert into staff values(2018, 1, 'Yamada');
insert into staff values(2018, 2, 'Suzuki');
insert into staff values(2019, 1, 'Horita');

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

PRIMARY KEY 制約を設定した joiny カラムと id カラムの値について、カラム毎であれば重複した値が格納されていますが、 2 つのカラムの組み合わせでは重複していないため問題なくデータが格納できました。

次に joiny カラムと id カラムの値の組み合わせが既存のデータの値と同じデータを追加してみます。

insert into staff values(2018, 2, 'Tatematsu');

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

Duplicate entry '値1-値2' for key 'PRIMARY' というエラーが発生しました。 joiny カラムと id カラムの組み合わせには PRIMARY KEY 制約が付いていますので、既存の値と同じ値を格納しようとするとエラーになります。

-- --

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

( Written by Tatsuo Ikura )

プロフィール画像

著者 / TATSUO IKURA

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