制約とインデックスは別個の論理エンティティです。たとえば、一意の制約はUSER_CONSTRAINTS
に表示されます (またはALL_CONSTRAINTS
またはDBA_CONSTRAINTS
)。インデックスはUSER_INDEXES
に表示されます (またはALL_INDEXES
またはDBA_INDEXES
。
一意性制約はインデックスによって強制されますが、一意でないインデックスを使用して一意性制約を強制することは可能です(場合によっては必要です)。たとえば、延期可能な一意性制約は、非一意性インデックスを使用して適用されます。列に非一意性インデックスを作成し、続いて一意性制約を作成する場合は、その非一意性インデックスを使用して一意性制約を適用することもできます。
実際には、一意のインデックスは、一意の制約の実装がインデックスを使用するため、一意の制約が発生するのと同じエラーを発生させるという点で、一意の延期不可能な制約と非常によく似ています。ただし、制約がないため、まったく同じではありません。したがって、これまで見てきたように、一意の制約はないため、列を参照する外部キー制約を作成することはできません。
一意の制約を作成できない一意のインデックスを作成できる場合があります。たとえば、条件付きの一意性を強制する関数ベースのインデックス。論理的削除をサポートするテーブルを作成したいが、COL1
であることを確認したい場合 削除されていないすべての行で一意です
SQL> ed
Wrote file afiedt.buf
1 CREATE TABLE t (
2 col1 number,
3 deleted_flag varchar2(1) check( deleted_flag in ('Y','N') )
4* )
SQL> /
Table created.
SQL> create unique index idx_non_deleted
2 on t( case when deleted_flag = 'N' then col1 else null end);
Index created.
SQL> insert into t values( 1, 'N' );
1 row created.
SQL> insert into t values( 1, 'N' );
insert into t values( 1, 'N' )
*
ERROR at line 1:
ORA-00001: unique constraint (SCOTT.IDX_NON_DELETED) violated
SQL> insert into t values( 1, 'Y' );
1 row created.
SQL> insert into t values( 1, 'Y' );
1 row created.
しかし、単純な一意の非関数ベースのインデックスについて話している場合、制約を作成するよりもインデックスを作成する方が実際に理にかなっているケースはおそらく比較的少ないでしょう。一方で、実際に大きな違いを生むケースは比較的少ないです。主キー制約ではなく一意制約を参照する外部キー制約を宣言することはほとんどないため、インデックスを作成するだけで制約を作成せずに何かを失うことはめったにありません。