2011-09-22 15 views
34

ユニークな制約(Oracle)を持たないユニーク索引を使用する目的は何かを明確にすることはできますか? 例: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"で失敗します。 私はこの動作によって完全に混乱しています。制約はありますか?

ユニークなインデックスを持たないユニークな制約を持つことができる理由を説明する記事が多数あります。それははっきりしていて、完璧な意味を持っていますしかし、私は制約のないユニークなインデックスの理由を理解していません。

答えて

39

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

ためのユニークである。しかし、我々はまっすぐにユニークな非機能ベースの指数の話をしている場合は、比較的おそらく存在していることを確認したい場合制約を作成するのではなく、索引を作成するほうが実際には意味をなさないケースはほとんどありません。一方、実際には大きな違いがあるケースは比較的少ない。主キー制約ではなく一意制約を参照する外部キー制約を宣言することはほとんどありません。そのため、インデックスを作成して制約を作成しないで、何かを失うことはめったにありません。

+0

答えていただきありがとうございます。今はっきりしています。私が本当に好きでないのは、制約とユニークなインデックスを持つ両方のケースで同じエラーコード( 'ORA-00001')です。 – a1ex07

+0

ユニークなFBIに対してユニークな制約を作成できるかどうかについて、「最後の賛辞」をいただきありがとうございます。 – orbfish

+0

ありがとう - これは私が見つけた2つの違いの唯一の明確な説明です。 一意の制約を宣言すると、オプティマイザに一意のインデックスよりも多くの情報が与えられます。それは本当ですか?それは、ユニークな制約が、制約なしでユニークなインデックスに対していくつかのパフォーマンス上の利点をもたらす可能性があることを意味しますか? – Mike

1

このコンテキストで役立つ別のポイントは次のとおりです。 既存の一意性制約を無効/削除しても、元の一意性インデックスは削除されません。ユニークなインデックスを明示的に削除する必要があります。

+2

これは正しくありません(少なくとも10g)。実際には、KEEP INDEXを指定してインデックスを保持するための一意制約を削除する必要があります。また、インデックスは一意である必要はありません。興味深いもの: – a1ex07

+0

しかし、11gからそうではありません。 – Syamjith

関連する問題