Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Oracle Unique Constraint und Unique Index

Eine Einschränkung und ein Index sind separate logische Einheiten. Eine eindeutige Einschränkung ist beispielsweise in USER_CONSTRAINTS sichtbar (oder ALL_CONSTRAINTS oder DBA_CONSTRAINTS ). Ein Index ist in USER_INDEXES sichtbar (oder ALL_INDEXES oder DBA_INDEXES ).

Eine Eindeutigkeitsbeschränkung wird durch einen Index erzwungen, obwohl es möglich (und manchmal notwendig) ist, eine Eindeutigkeitsbeschränkung mit einem nicht eindeutigen Index zu erzwingen. Eine aufschiebbare Eindeutigkeitsbeschränkung wird beispielsweise mithilfe eines nicht eindeutigen Index erzwungen. Wenn Sie einen nicht eindeutigen Index für eine Spalte und anschließend eine eindeutige Einschränkung erstellen, können Sie diesen nicht eindeutigen Index auch verwenden, um die eindeutige Einschränkung zu erzwingen.

In der Praxis verhält sich ein eindeutiger Index sehr ähnlich wie eine eindeutige, nicht aufschiebbare Einschränkung, da er den gleichen Fehler auslöst wie eine eindeutige Einschränkung, da die Implementierung von eindeutigen Einschränkungen den Index verwendet. Aber es ist nicht ganz dasselbe, weil es keine Beschränkung gibt. Wie Sie gesehen haben, gibt es also keine Unique-Einschränkung, sodass Sie keine Fremdschlüsseleinschränkung erstellen können, die auf die Spalte verweist.

Es gibt Fälle, in denen Sie einen eindeutigen Index erstellen können, in denen Sie keine eindeutige Einschränkung erstellen können. Ein funktionsbasierter Index zum Beispiel, der bedingte Eindeutigkeit erzwingt. Wenn ich eine Tabelle erstellen wollte, die logische Löschungen unterstützt, aber sicherstellen wollte, dass COL1 ist für alle nicht gelöschten Zeilen eindeutig

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.

Aber wenn wir über einen eindeutigen, eindeutigen, nicht funktionsbasierten Index sprechen, gibt es wahrscheinlich relativ wenige Fälle, in denen es wirklich sinnvoller ist, den Index zu erstellen, anstatt die Einschränkung zu erstellen. Andererseits gibt es relativ wenige Fälle, in denen es in der Praxis einen großen Unterschied macht. Sie möchten fast nie eine Fremdschlüssel-Einschränkung deklarieren, die auf eine Unique-Einschränkung verweist, anstatt auf eine Primärschlüssel-Einschränkung, sodass Sie selten etwas verlieren, wenn Sie nur den Index und nicht die Einschränkung erstellen.