sql >> Database >  >> RDS >> Oracle

Oracle unieke beperking en unieke index

Een beperking en een index zijn afzonderlijke logische entiteiten. Een unieke beperking is bijvoorbeeld zichtbaar in USER_CONSTRAINTS (of ALL_CONSTRAINTS of DBA_CONSTRAINTS ). Een index is zichtbaar in USER_INDEXES (of ALL_INDEXES of DBA_INDEXES ).

Een unieke beperking wordt afgedwongen door een index, hoewel het mogelijk (en soms noodzakelijk) is om een ​​unieke beperking af te dwingen met behulp van een niet-unieke index. Een uitstelbare unieke beperking wordt bijvoorbeeld afgedwongen met behulp van een niet-unieke index. Als u een niet-unieke index voor een kolom maakt en vervolgens een unieke beperking maakt, kunt u die niet-unieke index ook gebruiken om de unieke beperking af te dwingen.

In de praktijk gedraagt ​​een unieke index zich heel erg als een unieke, niet-uitstelbare beperking, omdat deze dezelfde fout oplevert als een unieke beperking sinds de implementatie van unieke beperkingen de index gebruikt. Maar het is niet helemaal hetzelfde omdat er geen beperking is. Dus, zoals je hebt gezien, is er geen unieke beperking, dus je kunt geen externe sleutelbeperking maken die naar de kolom verwijst.

Er zijn gevallen waarin u een unieke index kunt maken waarin u geen unieke beperking kunt maken. Een op functies gebaseerde index bijvoorbeeld die voorwaardelijke uniciteit afdwingt. Als ik een tabel wil maken die logische verwijderingen ondersteunt, maar ervoor zorgt dat COL1 is uniek voor alle niet-verwijderde rijen

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.

Maar als we het hebben over een rechtstreekse, unieke niet-functiegebaseerde index, zijn er waarschijnlijk relatief weinig gevallen waarin het echt zinvoller is om de index te maken in plaats van de beperking te creëren. Aan de andere kant zijn er relatief weinig gevallen waar het in de praktijk veel verschil maakt. U zou bijna nooit een externe-sleutelbeperking willen declareren die verwijst naar een unieke beperking in plaats van naar een primaire sleutelbeperking, dus u verliest zelden iets door alleen de index te maken en niet de beperking te creëren.



  1. 3 manieren om alle opgeslagen procedures weer te geven die verwijzen naar een tabel in PostgreSQL

  2. syntaxisfout met update-query bij join met een tabel

  3. Wacht Statistieken en Query Store

  4. Laravel Welsprekend selecteer alle rijen met max created_at