Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Restrição exclusiva do Oracle e índice exclusivo


Uma restrição e um índice são entidades lógicas separadas. Uma restrição exclusiva, por exemplo, é visível em USER_CONSTRAINTS (ou ALL_CONSTRAINTS ou DBA_CONSTRAINTS ). Um índice é visível em USER_INDEXES (ou ALL_INDEXES ou DBA_INDEXES ).

Uma restrição exclusiva é imposta por um índice, embora seja possível (e às vezes necessário) impor uma restrição exclusiva usando um índice não exclusivo. Uma restrição exclusiva adiável, por exemplo, é imposta usando um índice não exclusivo. Se você criar um índice não exclusivo em uma coluna e, posteriormente, criar uma restrição exclusiva, também poderá usar esse índice não exclusivo para impor a restrição exclusiva.

Na prática, um índice exclusivo age muito como uma restrição exclusiva e não adiável, pois gera o mesmo erro que uma restrição exclusiva gera, pois a implementação de restrições exclusivas usa o índice. Mas não é exatamente o mesmo porque não há restrição. Portanto, como você viu, não há restrição exclusiva, portanto, você não pode criar uma restrição de chave estrangeira que faça referência à coluna.

Há casos em que você pode criar um índice exclusivo que não pode criar uma restrição exclusiva. Um índice baseado em função, por exemplo, que impõe exclusividade condicional. Se eu quisesse criar uma tabela que suportasse exclusões lógicas, mas garantisse que COL1 é exclusivo para todas as linhas não excluídas
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.

Mas se estamos falando de um índice exclusivo e não baseado em função, provavelmente há relativamente poucos casos em que realmente faz mais sentido criar o índice em vez de criar a restrição. Por outro lado, existem relativamente poucos casos em que isso faz muita diferença na prática. Você quase nunca desejaria declarar uma restrição de chave estrangeira que referenciasse uma restrição exclusiva em vez de uma restrição de chave primária, então você raramente perde algo criando apenas o índice e não criando a restrição.