Domanda

Quando voglio una colonna di avere valori distinti, posso utilizzare un vincolo

create table t1(
id int primary key,
code varchar(10) unique NULL
);
go

o posso utilizzare un indice univoco

create table t2(
id int primary key,
code varchar(10) NULL
);
go

create unique index I_t2 on t2(code);

Colonne con vincoli univoci sembrano essere buoni candidati per gli indici univoci.

Ci sono motivi noti per utilizzare vincoli univoci e di non utilizzare indici univoci invece?

È stato utile?

Soluzione

Sotto il cofano un vincolo univoco è implementato allo stesso modo di un indice univoco - un indice è necessario per soddisfare in modo efficiente l'obbligo di rispettare il vincolo. Anche se l'indice è stato creato a seguito di un vincolo UNIQUE, il pianificatore query può utilizzare come qualsiasi altro indice, se lo vede come il modo migliore per affrontare una determinata query.

Quindi, per un database che supporta sia le caratteristiche della scelta di quale uso spesso scendere a stile preferito e coerenza.

Se si prevede di utilizzare l'indice come un indice (cioè il codice può contare su ricerca / selezione / filtraggio su quel campo per essere veloce) vorrei usare in modo esplicito un indice univoco (e commentare la fonte), piuttosto che un vincolo fare questa precisazione - in questo modo se il requisito di unicità è cambiata in una revisione successiva dell'applicazione che si (o qualche altro coder) saprà per assicurarsi che un indice non univoco è messo al posto di quello unico (solo la rimozione di un unico vincolo eliminerebbe l'indice completo). Anche un indice specifico può essere nominato in un hint di indice (cioè con (INDEX (ix_index_name)), che non credo sia il caso per l'indice creato dietro le quinte per la gestione di unicità come e 'difficile conoscere il suo nome.

Allo stesso modo se si è solo necessità di far rispettare l'unicità di regola business, piuttosto che il campo che necessitano di essere cercato o utilizzato per l'ordinamento allora io userei il vincolo, ancora una volta per rendere la destinazione d'uso più evidente quando qualcuno guarda il tuo tabella di definizione.

Si noti che se si utilizza sia un vincolo univoco e un indice univoco sullo stesso campo il database non sarà abbastanza luminosa per vedere la duplicazione, quindi vi ritroverete con due indici, che consumeranno spazio extra e inserti in fila di rallentamento / aggiornamenti.

Altri suggerimenti

In aggiunta ai punti in altre risposte, qui ci sono alcune differenze fondamentali tra i due.

. Nota: I messaggi di errore sono da SQL Server 2012

Errori

La violazione di un errore di unico vincolo rendimenti 2627.

Msg 2627, Level 14, State 1, Line 1
Violation of UNIQUE KEY constraint 'P1U_pk'. Cannot insert duplicate key in object 'dbo.P1U'. The duplicate key value is (1).
The statement has been terminated.

La violazione di un errore di unico rendimenti dell'indice 2601.

Msg 2601, Level 14, State 1, Line 1
Cannot insert duplicate key row in object 'dbo.P1' with unique index 'P1_u'. The duplicate key value is (1).
The statement has been terminated.

Disattivazione

Un vincolo univoco non può essere disabilitata.

Msg 11415, Level 16, State 1, Line 1
Object 'P1U_pk' cannot be disabled or enabled. This action applies only to foreign key and check constraints.
Msg 4916, Level 16, State 0, Line 1
Could not enable or disable the constraint. See previous errors.

Ma l'indice univoco dietro un vincolo di chiave primaria o un vincolo univoco può essere disattivato, come può un indice univoco. Cappello-tip Brain2000.

ALTER INDEX P1_u ON dbo.P1 DISABLE ;

Si noti il ??solito avvertimento che la disabilitazione di un indice cluster rende inaccessibili i dati.

Opzioni

vincoli unici supportano opzioni come FILLFACTOR e IGNORE_DUP_KEY indicizzazione, anche se questo non è stato il caso per tutte le versioni di SQL Server.

colonne incluse

indici non cluster possono includere colonne non indicizzate (definito un indice di copertura, questo rappresenta un notevole miglioramento delle prestazioni). Gli indici dietro PRIMARY KEY e UNIQUE non possono includere le colonne. Cappello-tip @ypercube.

Filtri

A Unique vincolo non può essere filtrata.

Un indice univoco può essere filtrato.

CREATE UNIQUE NONCLUSTERED INDEX Students6_DrivesLicence_u 
ON dbo.Students6( DriversLicenceNo ) WHERE DriversLicenceNo is not null ;

vincoli di chiave esterna

vincolo una chiave esterna non può fare riferimento un indice univoco filtrato, anche se può fare riferimento a un indice non filtrato unico (credo che questo è stato aggiunto in SQL Server 2005).

Naming

Durante la creazione di vincolo, specificando un nome di vincolo è opzionale (per tutti i cinque tipi di vincoli). Se non si specifica un nome allora MSSQL genererà una per te.

CREATE TABLE dbo.T1 (
    TID int not null PRIMARY KEY
) ;
GO
CREATE TABLE dbo.T2 (
    TID int not null CONSTRAINT T2_pk PRIMARY KEY
) ;

Durante la creazione di indici, è necessario specificare un nome.

Cappello-tip @ i-uno.

Link

http://technet.microsoft.com /en-us/library/aa224827(v=SQL.80).aspx

http://technet.microsoft.com/en-us/library/ ms177456.aspx

Per citare MSDN come fonte autorevole:

Non ci sono differenze significative tra la creazione di un vincolo UNIQUE e la creazione di un indice univoco che è indipendente da un vincolo . La convalida dei dati avviene nella stessa maniera, e Query Optimizer non fa differenza tra un indice univoco creato da un vincolo o creati manualmente. Tuttavia, creando un vincolo UNIQUE sulla colonna rende l'obiettivo dell'indice chiara ... maggiori informazioni qui

E ...

Il Motore di database crea automaticamente un indice univoco per far rispettare il requisito unicità del vincolo UNIQUE. Di conseguenza, se un tentare di inserire una riga duplicata è fatto, i rendimenti Motore di database un messaggio di errore che informa che il vincolo UNIQUE è stato violato e non aggiunge la riga alla tabella. A meno che un indice cluster è esplicitamente specificato, un unico, indice non cluster è stato creato da predefinito per far rispettare il vincolo ... maggiori informazioni UNICO qui

Altro in: https: // TechNet .microsoft.com / en-us / library / aa224827% 28v = sql.80% 29.aspx

Una delle principali differenze tra un vincolo univoco e un indice univoco è che un vincolo chiave esterna su un altro tavolo può fare riferimento a colonne che costituiscono un vincolo univoco. Questo non è vero per gli indici univoci. Inoltre, i vincoli unici sono definiti come parte dello standard ANSI, mentre gli indici non sono. Infine, vincolo univoco in considerazione per vivere nel regno della progettazione del database logico (che può essere implementata in modo diverso dai vari motori DB) mentre l'indice è aspetto fisico. Pertanto, vincolo univoco è più dichiarativo. Preferirei vincolo univoco in quasi tutti i casi.

In Oracle una grande differenza è che si può creare un indice-funzione unica, che non è fattibile con i vincoli unici:

Ad esempio

create unique index ux_test on my_table (case when amount != 0 then fk_xyz end);

Quindi fk_xyz è unico solo per il record che hanno amount != 0.

vincolo UNIQUE è preferibile rispetto indice univoco. Quando il vincolo non è univoco è necessario utilizzare un indice univoco regolare o non. Vincolo è anche un altro tipo di indice. Indice viene utilizzato per l'accesso rapido.

indici univoci può avere clausole WHERE. Ad esempio, è possibile creare indici per ogni anno sulla base della colonna di data

WHERE Sale_Date BETWEEN '2012-01-01' AND '2012-12-31'
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a dba.stackexchange
scroll top