Question

Quand je veux une colonne pour avoir des valeurs distinctes, je peux soit utiliser une contrainte

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

ou je peux utiliser un index unique

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

create unique index I_t2 on t2(code);

Les colonnes avec des contraintes uniques semblent être de bons candidats pour les index uniques.

Y a-t-il des raisons connues d'utiliser des contraintes uniques et de ne pas utiliser les index uniques à la place?

Était-ce utile?

La solution

Sous le capot une contrainte unique est mise en œuvre de la même manière comme un index unique - un index est nécessaire pour répondre efficacement à l'exigence de faire respecter la contrainte. Même si l'indice est créé à la suite d'une contrainte UNIQUE, le planificateur de requêtes peut l'utiliser comme tout autre indice si elle le considère comme la meilleure façon d'aborder une requête donnée.

Donc, pour une base de données qui prend en charge les caractéristiques dont le choix à l'utilisation viendra souvent à un style préféré et la cohérence.

Si vous prévoyez d'utiliser l'indice comme un indice (votre code peut compter sur la recherche / tri / filtrage sur ce champ pour être rapide) j'utiliser explicitement un index unique (et commenter la source) plutôt qu'une contrainte que cela soit clair - de cette façon si l'exigence d'unicité est modifiée dans une révision ultérieure de l'application que vous (ou un autre codeur) saura vous assurer un index non unique est mis en place de l'unique (il suffit de retirer un cadre unique contrainte supprimerait l'indice complètement). En outre un indice spécifique peut être nommé dans un indice d'index (c.-à-WITH (INDEX (ix_index_name)), que je ne pense pas est le cas pour l'index créé dans les coulisses de la gestion unique comme il est rare de connaître son nom.

De même, si vous ne avoir besoin d'assurer l'unicité en règle d'affaires plutôt que sur le terrain ont besoin d'être recherché ou utilisé pour trier puis j'utiliser la contrainte, encore une fois pour faire quelqu'un usage prévu plus évident quand d'autre regarde votre définition table.

Notez que si vous utilisez à la fois une contrainte unique et un index unique sur le même champ de la base de données ne sera pas assez brillant pour voir la duplication, de sorte que vous finirez avec deux index qui consomment de l'espace supplémentaire et lent insertions de ligne descendante / mises à jour.

Autres conseils

En plus des points dans d'autres réponses, voici quelques différences importantes entre les deux.

Note:. Les messages d'erreur sont de SQL Server 2012

Erreurs

La violation d'un rendement de contrainte unique erreur 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 violation d'un index unique retourne l'erreur 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.

Désactivation

Une contrainte unique ne peut pas être désactivée.

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.

Mais l'index unique derrière une contrainte de clé primaire ou une contrainte unique peut être désactivée, tout comme un indice unique. Hat pointe Brain2000.

ALTER INDEX P1_u ON dbo.P1 DISABLE ;

Notez l'avertissement habituel que la désactivation d'un index ordonné en clusters rend l'inaccessible de données.

Options

contraintes uniques en charge l'indexation des options comme FILLFACTOR et IGNORE_DUP_KEY, bien que cela n'a pas été le cas pour toutes les versions de SQL Server.

Colonnes incluses

index non cluster peuvent inclure des colonnes non indexées (appelé un indice de recouvrement, ceci est une amélioration de la performance majeur). Les indices derrière les contraintes PRIMARY KEY et UNIQUE ne peut pas inclure des colonnes. Hat pointe @ypercube.

Filtrage

Une contrainte unique ne peut pas être filtrée.

Un index unique peut être filtré.

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

clés étrangères

Une contrainte de clé étranger ne peut pas faire référence à un index unique filtré, mais il peut faire référence à un index unique non filtré (je pense que cela a été ajouté dans SQL Server 2005).

Attribution d'un nom

Lors de la création de contrainte, en spécifiant un nom de contrainte est facultative (pour les cinq types de contraintes). Si vous ne spécifiez pas de nom alors MSSQL va générer pour vous.

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

Lors de la création d'index, vous devez spécifier un nom.

Hat-pointe @ i-un.

Liens

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

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

Pour citer MSDN comme une source:

  

Il n'y a pas de différence significative entre la création d'une contrainte UNIQUE et la création d'un index unique qui est indépendant d'une contrainte . la validation des données se produit de la même manière, et l'optimiseur de requête ne fait pas de distinction entre un index unique créé par une contrainte ou manuellement créé. Cependant, la création d'une contrainte UNIQUE sur la colonne rend l'objectif de l'indice clair ... plus d'info ici

...

  

Le moteur de base de données crée automatiquement un index UNIQUE pour faire respecter   l'exigence d'unicité de la contrainte UNIQUE. Par conséquent, si un   essayez d'insérer une ligne en double est fait, le rendement du moteur de base de données   un message d'erreur indiquant la contrainte UNIQUE a été violé   et ne pas ajouter la ligne à la table. À moins qu'un index ordonné en clusters est   explicitement spécifié, un index unique, nonclustered est créé par   par défaut pour appliquer la contrainte UNIQUE ... plus d'infos ici

Autre dans: https: // technet .microsoft.com / fr-fr / bibliothèque / aa224827% = 28V sql.80% 29.aspx

L'une des principales différences entre une contrainte unique et un index unique est qu'une contrainte de clé étrangère sur une autre table peut référencer des colonnes qui constituent une contrainte unique. Cela ne vaut pas pour les index uniques. En outre, les contraintes uniques sont définies dans le cadre de la norme ANSI, alors que les indices ne sont pas. Enfin, contrainte unique considéré à vivre dans le domaine de la conception de base de données logique (qui peut être mis en œuvre différemment par les différents moteurs de DB), tandis que l'indice est un aspect physique. Par conséquent, la contrainte unique est plus déclarative. Je préfère contrainte unique dans presque tous les cas.

Dans Oracle une grande différence est que vous pouvez créer un index de fonction unique, ce qui est faisable avec des contraintes uniques:

Par exemple

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

Alors fk_xyz est seulement unique pour l'enregistrement qui ont amount != 0.

UNIQUE Constraint est préférée sur UNIQUE Index. Lorsque la contrainte n'est pas unique, vous devez utiliser un index régulier ou non unique. Contrainte est également un autre type d'index. L'indice est utilisé pour un accès plus rapide.

Les index uniques peuvent avoir des clauses WHERE. Par exemple, vous pouvez créer des index pour chaque année en fonction de la colonne de date

WHERE Sale_Date BETWEEN '2012-01-01' AND '2012-12-31'
Licencié sous: CC-BY-SA avec attribution
Non affilié à dba.stackexchange
scroll top