MySQLでカラムにUNIQUEを設定する(一意な値にする)

MySQL MySQL

MySQLでテーブルにユニーク(UNIQUE)設定する方法について書きました。
作成したテーブルにユニーク(UNIQUE)設定するには、テーブル作成時にカラムに対して、UNIQUEをつけておくと良いです。

MySQLのバージョン8.0.32で、動作を検証しています。

テーブルのカラムに一意制約(UNIQUE)を設定する

MySQLでテーブルのカラムに一意制約(UNIQUE)を追加するには、テーブル作成時にカラムに対してUNIQUEを設定します。
UNIQUEを設定すると、既にテーブルのカラムに入っているデータと、同じデータを入れることができなくなります。

例えば、下記のようにテーブルを作成します。

CREATE TABLE users (
  id BIGINT NOT NULL AUTO_INCREMENT,
  name VARCHAR(128) UNIQUE,
  age SMALLINT,
  birthday DATE,
  PRIMARY KEY (id)
);

usersテーブルを作成しました。
usersテーブルのnameカラムにUNIQUEを設定しています。

これで、データ追加や更新時にnameカラムには同じ値を入れることはできません。
NULLはUNIQUE制約にかからずに、追加することができます。

SQLを実行してテーブルを作成します。

mysql> CREATE TABLE users (
    ->   id BIGINT NOT NULL AUTO_INCREMENT,
    ->   name VARCHAR(128) UNIQUE,
    ->   age SMALLINT,
    ->   birthday DATE,
    ->   PRIMARY KEY (id)
    -> );

Query OK, 0 rows affected (0.02 sec)

テーブルが作成されました。

テーブル作成(CREATE TABLE)については、こちらの記事を確認してみてください。
・MySQLでテーブルを作成する(CREATE TABLE)

同じ値を追加(インサート)してみる

作成したusersテーブルに、下記のように1行データがある状態です。

mysql> SELECT * FROM users;
+----+------+------+------------+
| id | name | age  | birthday   |
+----+------+------+------------+
|  1 | taro |   25 | 1998-01-01 |
+----+------+------+------------+
1 row in set (0.00 sec)

この状態で、下記のように新規に1行データを追加してみます。
nameカラムが重複しているデータです。

INSERT INTO users (name, age, birthday) VALUE ('taro', '34', '1989-01-01');

そうすると、下記のようにERROR 1062 (23000)エラーが発生しました。
同じ名前のユーザーが追加できなくなったことが確認できました。

ERROR 1062 (23000): Duplicate entry 'taro' for key 'users.name'

同じ値を更新(アップデート)してみる

作成したusersテーブルに、下記のように2行データがある状態です。

mysql> SELECT * FROM users;
+----+--------+------+------------+
| id | name   | age  | birthday   |
+----+--------+------+------------+
|  1 | taro   |   34 | 1989-01-01 |
|  2 | hanako |   33 | 1988-01-01 |
+----+--------+------+------------+
2 rows in set (0.00 sec)

この状態で、idが「1」のtaroさんの名前を、2行目と同じhanakoに変えてみます。

UPDATE users SET name = 'hanako' WHERE id = 1;

SQLを実行すると、下記のように、先ほどと同じERROR 1062 (23000)エラーが発生しました。

ERROR 1062 (23000): Duplicate entry 'hanako' for key 'users.name'

このように、テーブル内に同じデータを重複させることができなくなります。

テーブルのカラムに一意制約(UNIQUE)を複数設定する

テーブルのカラムにUNIQUE制約を複数設定して、一意にするには、テーブル作成時にUNIQUEを指定して設定したいカラムを並べます。
複数を一括して設定すると、どちらの値も同じときのみエラーになります。

例えば、下記のように書くと、一括で設定できます。

CREATE TABLE users (
  id BIGINT NOT NULL AUTO_INCREMENT,
  name VARCHAR(128),
  age SMALLINT,
  birthday DATE,
  UNIQUE (name, age),
  PRIMARY KEY (id)
);

こうすると、2つのカラム(nameage)の値に重複しているのみエラーになります。
実際に実行して、テーブルを作成します。

同じ値のデータを入れてみる

テーブルを作成したので、同じデータが重複しないか試してみます。
既に下記のようにデータを入れました。

mysql> SELECT * FROM users;
+----+------+------+------------+
| id | name | age  | birthday   |
+----+------+------+------------+
|  1 | taro |   34 | 1989-01-01 |
+----+------+------+------------+
1 row in set (0.00 sec)

このときに、下記のように名前(name)は同じで、年齢(age)が違うSQLを実行します。

mysql> INSERT INTO users (name, age, birthday) VALUE ('taro', '33', '1988-01-01');
Query OK, 1 row affected (0.00 sec)

そのまま実行されて、下記のようにusersテーブルのデータは2行になります。

mysql> SELECT * from users;
+----+------+------+------------+
| id | name | age  | birthday   |
+----+------+------+------------+
|  1 | taro |   34 | 1989-01-01 |
|  2 | taro |   33 | 1988-01-01 |
+----+------+------+------------+
2 rows in set (0.00 sec)

このように、複数に一括してUNIQUEを設定したときには、2つが同じときでないとエラーは発生しません。
このテーブルの状態で、下記のようにSQLを実行します。

INSERT INTO users (name, age, birthday) VALUE ('taro', '33', '1988-01-01');

そうすると、ERROR 1062 (23000)エラーが発生しました。
nameageカラムが同じ値のためエラーになりました。

ERROR 1062 (23000): Duplicate entry 'taro-33' for key 'users.name'

個別に一意制約(UNIQUE)をつけたとき

一括して設定しましたが、個別に下記のようにUNIQUEをつけたときには、挙動が変わるので注意しましょう。

CREATE TABLE users (
  id BIGINT NOT NULL AUTO_INCREMENT,
  name VARCHAR(128) UNIQUE,
  age SMALLINT UNIQUE,
  birthday DATE,
  PRIMARY KEY (id)
);

この場合は、どちらかのカラムの値が既にあるとエラーになります。
nameカラムに同じ値が既にあるか、ageカラムに既に同じ値があるか、どちらかでERROR 1062 (23000):エラーが発生します。

MySQLでカラムにUNIQUE設定のまとめ

今回はMySQLでカラムにUNIQUEを設定する方法を書きました。
記事の内容をまとめると、下記のようになります。

・カラムにUNIQUEをつけると、重複しないユニークな値のみを許可するようになる(一意制約)
・UNIQUEが設定されたカラムに、既にテーブルにある値と同じ値を追加・更新しようとするとエラーになる。
・UNIQUE制約を複数のカラムに一緒に設定すると、どちらも同じ値だったときにエラーになる。

UNIQUE(一意制約)をつけることで、同じ値は入らないようになりました。

同じ値を入れたくないカラムには、あらかじめ設定しておくと良いかと思います。
プログラムのミスなどで値が重複登録されようとしても、MySQL側ではじくことができます。

コメント

タイトルとURLをコピーしました