データベースの制約の1つに一意制約(UNIQUE)があり、一意制約(UNIQUE)を設定した列では、重複したデータを追加することができない。ただ、NULL値については、データベースの種類によっては、一意制約(UNIQUE)を設定した列でも複数のデータを追加できる。
今回は、Oracle・MySQL・PostgreSQL・SQL Serverの各DB上で、一意制約(UNIQUE)の挙動を確認してみたので、その結果を共有する。
前提条件
Oracle XEのインストールが完了していること。
また、下記記事に記載されている、MySQLとPostgreSQLでのユーザー作成とUSER_DATAテーブル作成が完了していること。
さらに、下記記事の「前提条件」の内容が完了していること。
やってみたこと
Oracleの場合の実行結果
Oracleの場合の実行結果は以下の通りで、一意制約(UNIQUE)を設定した列でも、NULL値のデータは複数追加できる。
1) 検証用のemployeeテーブルを追加する。列「name」に一意制約(UNIQUE)を設定している。
1 2 3 4 5 | create table employee ( emp_id integer primary key not null , name varchar2(40) , constraint uq_name unique(name) ) |
2) 検証用のemployeeテーブルに、検証用のデータを追加する。
1 2 3 4 | insert into employee values (1, 'テスト プリン1'); insert into employee values (2, ' '); insert into employee values (3, null); commit; |
3) 検証用のemployeeテーブルのデータの中身は、以下の通り。
1 | select * from employee order by emp_id |
4) 一意制約(UNIQUE)を設定した列「name」にNULL・空文字以外の重複データを追加すると、一意制約エラーになることが確認できる。
1 | insert into employee values (4, 'テスト プリン1') |
5) 一意制約(UNIQUE)を設定した列「name」に空文字の重複データを追加すると、一意制約エラーになることが確認できる。
1 | insert into employee values (4, ' ') |
6) 一意制約(UNIQUE)を設定した列「name」にNULL値の重複データを追加すると、正常にデータを追加できることが確認できる。
1 | insert into employee values (4, null) |
7) コミットして検証用のemployeeテーブルのデータの中身を確認すると、以下のように、NULL値の重複データが含まれていることが確認できる。
1 | commit |
1 | select * from employee order by emp_id |
MySQLの場合の実行結果
MySQLの場合の実行結果は以下の通りで、一意制約(UNIQUE)を設定した列でも、NULL値のデータは複数追加できる。
1) 検証用のemployeeテーブルを追加する。列「name」に一意制約(UNIQUE)を設定している。
1 2 3 4 5 | create table employee ( emp_id int primary key not null , name varchar(40) , constraint uq_name unique(name) ) |
2) 検証用のemployeeテーブルに、検証用のデータを追加する。
1 2 3 4 | insert into employee values (1, 'テスト プリン1'); insert into employee values (2, ' '); insert into employee values (3, null); commit; |
3) 検証用のemployeeテーブルのデータの中身は、以下の通り。
1 | select * from employee order by emp_id |
4) 一意制約(UNIQUE)を設定した列「name」にNULL・空文字以外の重複データを追加すると、一意制約エラーになることが確認できる。
1 | insert into employee values (4, 'テスト プリン1') |
5) 一意制約(UNIQUE)を設定した列「name」に空文字の重複データを追加すると、一意制約エラーになることが確認できる。
1 | insert into employee values (4, ' ') |
6) 一意制約(UNIQUE)を設定した列「name」にNULL値の重複データを追加すると、正常にデータを追加できることが確認できる。
1 | insert into employee values (4, null) |
7) コミットして検証用のemployeeテーブルのデータの中身を確認すると、以下のように、NULL値の重複データが含まれていることが確認できる。
1 | commit |
1 | select * from employee order by emp_id |
PostgreSQLの場合の実行結果
PostgreSQLの場合の実行結果は以下の通りで、一意制約(UNIQUE)を設定した列でも、NULL値のデータは複数追加できる。
1) 検証用のemployeeテーブルを追加する。列「name」に一意制約(UNIQUE)を設定している。
1 2 3 4 5 | create table employee ( emp_id integer primary key not null , name varchar(40) , constraint uq_name unique(name) ) |
2) 検証用のemployeeテーブルに、検証用のデータを追加する。
1 2 3 | insert into employee values (1, 'テスト プリン1'); insert into employee values (2, ' '); insert into employee values (3, null); |
3) 検証用のemployeeテーブルのデータの中身は、以下の通り。
1 | select * from employee order by emp_id |
4) 一意制約(UNIQUE)を設定した列「name」にNULL・空文字以外の重複データを追加すると、一意制約エラーになることが確認できる。
1 | insert into employee values (4, 'テスト プリン1') |
5) 一意制約(UNIQUE)を設定した列「name」に空文字の重複データを追加すると、一意制約エラーになることが確認できる。
1 | insert into employee values (4, ' ') |
6) 一意制約(UNIQUE)を設定した列「name」にNULL値の重複データを追加すると、正常にデータを追加できることが確認できる。
1 | insert into employee values (4, null) |
7) 検証用のemployeeテーブルのデータの中身を確認すると、以下のように、NULL値の重複データが含まれていることが確認できる。
1 | select * from employee order by emp_id |
SQL Serverの場合の実行結果
SQL Serverの場合の実行結果は以下の通りで、一意制約(UNIQUE)を設定した列でも、NULL値のデータは複数追加できる。
1) 検証用のemployeeテーブルを追加する。列「name」に一意制約(UNIQUE)を設定している。
1 2 3 4 5 | create table dbo.employee ( emp_id int primary key not null , name nvarchar(40) , constraint uq_name unique(name) ) |
2) 検証用のemployeeテーブルに、検証用のデータを追加する。
1 2 3 | insert into dbo.employee values (1, 'テスト プリン1'); insert into dbo.employee values (2, ' '); insert into dbo.employee values (3, null); |
3) 検証用のemployeeテーブルのデータの中身は、以下の通り。
1 | select * from dbo.employee order by emp_id |
4) 一意制約(UNIQUE)を設定した列「name」にNULL・空文字以外の重複データを追加すると、一意制約エラーになることが確認できる。
1 | insert into dbo.employee values (4, 'テスト プリン1') |
5) 一意制約(UNIQUE)を設定した列「name」に空文字の重複データを追加すると、一意制約エラーになることが確認できる。
1 | insert into dbo.employee values (4, ' ') |
6) 一意制約(UNIQUE)を設定した列「name」にNULL値の重複データを追加すると、他のDBとは違い、一意制約エラーになることが確認できる。
1 | insert into dbo.employee values (4, null) |
なお、NULL値の重複データを追加してもエラーにならないように一意制約を設定する方法については、以下の記事を参照のこと。
要点まとめ
- データベースの制約の1つに一意制約(UNIQUE)があり、一意制約(UNIQUE)を設定した列では、重複したデータを追加することができない。
- Oracle・MySQL・PostgreSQLの場合は、一意制約(UNIQUE)を設定した列でもNULL値の重複データは複数追加でき、SQL Serverの場合は、一意制約(UNIQUE)を設定した列にNULL値の重複データは複数追加できない違いがある。