UNIQUE制約(ユニーク制約を設定する)

テーブルを作成するときにカラムに UNIQUE 制約をつけることでカラムに重複した値を格納することができなくなります。ここでは MySQL における UNIQUE 制約の使い方について解説します。

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

(Last modified: )

UNIQUE制約の使い方

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

CREATE TABLE db_name.tbl_name
  (col_name data_type UNIQUE, ...)

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

CREATE TABLE db_name.tbl_name
  (col_name data_type, ..., UNIQUE [index_name] (col_name, ...))

UNIQUE 制約が設定されたカラムには重複した値を格納できなくなります。この点は PRIMARY KEY 制約と似ていますが、 UNIQUE 制約の場合は値として NULL を格納することができ、また複数のカラムに NULL を格納できます。また複数のカラムに対して UNIQUE 制約を設定することができます。

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

create table staff(id int unique, name varchar(10));

UNIQUE制約の使い方(1)

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

show columns from staff;

UNIQUE制約の使い方(2)

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

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

show index from staff\G

UNIQUE制約の使い方(3)

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

-- --

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

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

UNIQUE制約の使い方(4)

UNIQUE 制約を設定したカラムの値が既存のデータの値と重複しておらず、また NULL も格納することできて NULL に関してだけは複数のカラムに格納されても問題ないため正常に格納することができました。

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

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

UNIQUE制約の使い方(5)

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

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

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

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

CREATE TABLE db_name.tbl_name
  (col_name1 data_type, col_name2 data_type, ..., 
   UNIQUE [index_name] (col_name1, col_name2, ...))

UNIQUE 制約を設定すると自動でインデックスが作成されます。インデックス名( index_name )は省略可能です。省略した場合は対象となるカラム名などから自動的にインデックス名が付けられます。

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

create table staff(joiny int, id int, name varchar(10), unique joiny_id_index (joiny, id));

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

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

show columns from staff;

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

UNIQUE 制約が設定された joiny カラムと id カラムには自動でインデックスが作成されており、 joiny カラムの Key カラムの値に MUL と設定されています。今回は複数のカラムの組み合わせに対して UNIQUE 制約を設定していますが、最初のカラムに MUL が設定されるようです。

UNIQUE 制約がどのカラムに対して設定されているのかを確認するには SHOW CREATE TABLE 文を使うと確認できます。

show create table staff\G

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

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

show index from staff\G

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

同じインデックス名がついた 2 つのインデックスが作成されています。違いは 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(NULL, 1, 'Horita');
insert into staff values(NULL, 2, 'Endou');

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

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

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

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

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

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

ただ、 joiny カラムと id カラムの値の組み合わせが既存のデータの値と同じ場合であっても、 NULL が含まれている場合はエラーとなりません。次のようなデータを追加してみます。

insert into staff values(NULL, 1, 'Oomura');

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

最後に追加したデータは既に格納済みのデータと joiny カラムと id カラムの値の組み合わせが同じですが、カラムに NULL が含まれている場合は重複した値とは見なされないためエラーとはならずデータが格納されました。

-- --

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

( Written by Tatsuo Ikura )

Profile
profile_img

著者 / TATSUO IKURA

プログラミングや開発環境構築の解説サイトを運営しています。