43

一意の制約(Oracle)のない一意のインデックスを持つ目的を誰かが明確にすることはできますか? 例えば、

create table test22(id int, id1 int, tmp varchar(20));
create unique index idx_test22 on test22(id);
insert into test22(id, id1, tmp) values (1, 2, 'aaa'); // ok
insert into test22(id, id1, tmp) values (1, 2, 'aaa'); // fails, ORA-00001: unique   
  // constraint (TEST.IDX_TEST22) violated

これまでのところ、制約があるようです。しかし

create table test33(id int not null primary key, 
test22_id int not null, 
foreign key(test22_id) references test22(id) );

も失敗し"ORA-02270: no matching unique or primary key for this column-list"ます。私はこの行動に完全に混乱しています。制約はありますか?

一意のインデックスを使用せずに一意の制約を設定できる理由を説明する記事は多数あります。それは明確で、完全に理にかなっています。ただし、制約のない一意のインデックスの理由がわかりません。

4

4 に答える 4

58

制約とインデックスは別個の論理エンティティです。たとえば、一意の制約は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.

しかし、単純な一意の非関数ベースのインデックスについて話している場合、制約を作成するよりもインデックスを作成する方が本当に理にかなっているケースは比較的少ないでしょう。一方で、実際に大きな違いが生じるケースは比較的少ないです。主キー制約ではなく一意制約を参照する外部キー制約を宣言することはほとんどないため、インデックスを作成するだけで制約を作成しないことで何かが失われることはほとんどありません。

于 2011-09-22T22:01:03.840 に答える