且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Oracle唯一约束和唯一索引

更新时间:2023-02-04 15:15:07

约束和索引是独立的逻辑实体.例如,唯一约束在USER_CONSTRAINTS(或ALL_CONSTRAINTSDBA_CONSTRAINTS)中可见.索引在USER_INDEXES(或ALL_INDEXESDBA_INDEXES)中可见.

A constraint and an index are separate logical entities. A unique constraint, for example, is visible in USER_CONSTRAINTS (or ALL_CONSTRAINTS or DBA_CONSTRAINTS). An index is visible in USER_INDEXES (or ALL_INDEXES or DBA_INDEXES).

唯一约束由索引强制执行,尽管有可能(有时是必要的)使用非唯一索引强制执行唯一约束.例如,使用非唯一索引强制实施可延迟的唯一约束.如果您在列上创建非唯一索引并随后创建唯一约束,则也可以使用该非唯一索引来实施唯一约束.

A unique constraint is enforced by an index though it is possible (and sometimes necessary) to enforce a unique constraint using a non-unique index. A deferrable unique constraint, for example, is enforced using a non-unique index. If you create a non-unique index on a column and subsequently create a unique constraint, you can also use that non-unique index to enforce the unique constraint.

在实践中,唯一索引的行为非常类似于唯一的,不可延迟的约束,因为它会产生与唯一约束所引起的错误相同的错误,因为唯一约束的实现会使用索引.但这并不完全相同,因为没有约束.因此,如您所见,没有唯一约束,因此您不能创建引用该列的外键约束.

In practice, a unique index acts very much like a unique, non-deferrable constraint in that it raises the same error that a unique constraint raises since the implementation of unique constraints uses the index. But it is not quite the same because there is no constraint. So, as you've seen, there is no unique constraint so you cannot create a foreign key constraint that references the column.

在某些情况下,您可以创建唯一索引,而无法创建唯一约束.例如,基于函数的索引强制执行条件唯一性.如果我想创建一个支持逻辑删除的表,但要确保COL1对于所有未删除的行都是唯一的

There are cases where you can create a unique index that you cannot create a unique constraint. A function-based index, for example, that enforces conditional uniqueness. If I wanted to create a table that supported logical deletes but ensure that COL1 is unique for all non-deleted rows

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.

但是,如果我们谈论的是一个直接的,基于非函数的唯一索引,那么在相对少数情况下,创建索引比创建约束更有意义.另一方面,在实践中影响很大的情况相对较少.您几乎永远不会想要声明引用唯一约束而不是主键约束的外键约束,因此仅通过创建索引而不创建约束就很少丢失某些东西.

But if we're talking about a straight unique non-function based index, there are probably relatively few cases where it really makes more sense to create the index rather than creating the constraint. On the other hand, there are relatively few cases where it makes much difference in practice. You'd almost never want to declare a foreign key constraint that referenced a unique constraint rather than a primary key constraint so you rarely lose something by only creating the index and not creating the constraint.