有人能澄清什么是有唯一索引没有唯一约束(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,'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:此列列表没有匹配的唯一或主键”。
我完全对这种行为感到困惑。是否有约束或不?
有很多文章解释为什么可能有一个唯一的约束没有唯一索引;这是清楚和完美的意义。然而,我不明白唯一索引的原因没有约束。
谢谢你的帮助。
约束和索引是单独的逻辑实体。例如,唯一约束在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.
但是,如果我们谈论一个直接的,独立的非基于函数的索引,那么创建索引而不是创建约束更有意义。另一方面,在实践中有很大差异的情况相对较少。你几乎不想声明一个引用唯一约束而不是主键约束的外键约束,因此很少通过创建索引而不创建约束来损失某些东西。