ただメモができるだけのブラウザアプリ「TextArea」はこちらw

MySQLでユニークインデックスを貼る際のDuplicate entry fuga for key hoge エラー

MySQLでユニークインデックスを貼る際のDuplicate entry fuga for key hoge エラーについてです。

まず、ユニークインデックスを貼る際の構文については以下の通りです。

alter table {テーブル名} add unique({インデックスを貼るカラム});

インデックスを貼るカラムはカンマ「,」区切りで複数指定できます。

ユニークインデックスを貼る際のDuplicateエラーがどんな場合に発生するか記載していきます。

MySQL8系とMySQL5.7系で若干挙動が異なります。具体的には以下の挙動となります。

Duplicateエラーの発生条件

MySQL8系とMySQL5.7系ともに複数レコードに同じ値があるカラムにはユニークインデックスは貼れない(Duplicateエラーになる)
MySQL8系とMySQL5.7系ともに複数レコードにNULLがあるカラムにはユニークインデックスは貼れる
MySQL5.7系の場合、末尾の半角スペースのみの違いしかない値が複数レコードあるカラムにはユニークインデックスは貼れない(Duplicateエラーになる)(MySQL8系では貼れる)

検証時のコマンドと結果を記載していきます。

MySQL8系

まずバージョン確認

select version();

+-----------+
| version() |
+-----------+
| 8.0.37    |
+-----------+

複数レコードに同じ値があるカラム場合

# テーブル作成
create table user (id int, name varchar(10));

# データ登録
insert into user values (1, 'test_user'),(2, 'test_user');

# ユニークインデックスを貼る
alter table user add unique(name);

# 結果:エラー
ERROR 1062 (23000): Duplicate entry 'test_user' for key 'user.name'

# テーブル削除
drop table user;

複数レコードにNULLがあるカラム場合

# テーブル作成
create table user (id int, name varchar(10));

# データ登録
insert into user values (1, null),(2, null);

# ユニークインデックスを貼る
alter table user add unique(name);

# 結果:成功
Query OK, 0 rows affected (0.02 sec)

# テーブル削除
drop table user;

末尾にスペースがある場合

# テーブル作成
create table user (id int, name varchar(10));

# データ登録
insert into user values (1, 'test_user'),(2, 'test_user ');

# ユニークインデックスを貼る
alter table user add unique(name);

# 結果:成功
Query OK, 0 rows affected (0.02 sec)

# テーブル削除
drop table user;

途中にスペースがある場合

# テーブル作成
create table user (id int, name varchar(10));

# データ登録
insert into user values (1, 'testuser'),(1, 'test user');

# ユニークインデックスを貼る
alter table user add unique(id,name);

# 結果:成功
Query OK, 0 rows affected (0.02 sec)

# テーブル削除
drop table user;

先頭にスペースがある場合

# テーブル作成
create table user (id int, name varchar(10));

# データ登録
insert into user values (1, 'test_user'),(1, ' test_user');

# ユニークインデックスを貼る
alter table user add unique(id,name);

# 結果:成功
Query OK, 0 rows affected (0.01 sec)

# テーブル削除
drop table user;

MySQL5.7系

まずバージョン確認

select version();

+-----------+
| version() |
+-----------+
| 5.7.44    |
+-----------+

複数レコードに同じ値があるカラム場合

# テーブル作成
create table user (id int, name varchar(10));

# データ登録
insert into user values (1, 'test_user'),(2, 'test_user');

# ユニークインデックスを貼る
alter table user add unique(name);

# 結果:エラー
ERROR 1062 (23000): Duplicate entry 'test_user' for key 'name'

# テーブル削除
drop table user;

複数レコードにNULLがあるカラム場合

# テーブル作成
create table user (id int, name varchar(10));

# データ登録
insert into user values (1, null),(2, null);

# ユニークインデックスを貼る
alter table user add unique(name);

# 結果:成功
Query OK, 0 rows affected (0.02 sec)

# テーブル削除
drop table user;

末尾にスペースがある場合

# テーブル作成
create table user (id int, name varchar(10));
# データ登録
insert into user values (1, 'test_user'),(2, 'test_user ');

# ユニークインデックスを貼る
alter table user add unique(name);

# 結果:エラー
ERROR 1062 (23000): Duplicate entry 'test_user' for key 'name'

# テーブル削除
drop table user;

途中にスペースがある場合

# テーブル作成
create table user (id int, name varchar(10));

# データ登録
insert into user values (1, 'testuser'),(1, 'test user');

# ユニークインデックスを貼る
alter table user add unique(id,name);

# 結果:成功
Query OK, 0 rows affected (0.02 sec)

# テーブル削除
drop table user;

先頭にスペースがある場合

# テーブル作成
create table user (id int, name varchar(10));

# データ登録
insert into user values (1, 'test_user'),(1, ' test_user');

# ユニークインデックスを貼る
alter table user add unique(id,name);

# 結果:成功
Query OK, 0 rows affected (0.01 sec)

# テーブル削除
drop table user;

まとめ

概ね想定通りでしたが、「MySQL5.7系の場合、末尾の半角スペースのみの違いしかない値が複数レコードあるカラムにはユニークインデックスは貼れない」のは意外でした!!

Duplicateエラーの発生条件まとめ

MySQL8系とMySQL5.7系ともに複数レコードに同じ値があるカラムにはユニークインデックスは貼れない
MySQL8系とMySQL5.7系ともに複数レコードにNULLがあるカラムにはユニークインデックスは貼れる
MySQL5.7系の場合、末尾の半角スペースのみの違いしかない値が複数レコードあるカラムにはユニークインデックスは貼れない(MySQL8系では貼れる)

スポンサーリンク
MySQL
フォローする
さゆフィクション