sql >> Base de Datos >  >> RDS >> Oracle

Restricción única de Oracle e índice único

Una restricción y un índice son entidades lógicas separadas. Una restricción única, por ejemplo, es visible en USER_CONSTRAINTS (o ALL_CONSTRAINTS o DBA_CONSTRAINTS ). Un índice es visible en USER_INDEXES (o ALL_INDEXES o DBA_INDEXES ).

Un índice impone una restricción única, aunque es posible (ya veces necesario) imponer una restricción única utilizando un índice no único. Una restricción única diferible, por ejemplo, se aplica mediante un índice no único. Si crea un índice no único en una columna y luego crea una restricción única, también puede usar ese índice no único para aplicar la restricción única.

En la práctica, un índice único actúa de manera muy parecida a una restricción única no diferible en el sentido de que genera el mismo error que genera una restricción única, ya que la implementación de restricciones únicas utiliza el índice. Pero no es exactamente lo mismo porque no hay ninguna restricción. Entonces, como ha visto, no hay una restricción única, por lo que no puede crear una restricción de clave externa que haga referencia a la columna.

Hay casos en los que puede crear un índice único que no puede crear una restricción única. Un índice basado en funciones, por ejemplo, que impone la exclusividad condicional. Si quisiera crear una tabla que admitiera eliminaciones lógicas pero asegurarme de que COL1 es único para todas las filas no eliminadas

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.

Pero si estamos hablando de un índice directo único no basado en funciones, probablemente haya relativamente pocos casos en los que realmente tenga más sentido crear el índice en lugar de crear la restricción. Por otro lado, hay relativamente pocos casos en los que hace mucha diferencia en la práctica. Casi nunca querrá declarar una restricción de clave externa que haga referencia a una restricción única en lugar de una restricción de clave principal, por lo que rara vez perderá algo al crear solo el índice y no crear la restricción.