Quand je veux qu'une colonne ait 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 des index uniques.
Existe-t-il des raisons connues d'utiliser des contraintes uniques et de ne pas utiliser d'index uniques?
Réponses:
Sous le capot, une contrainte unique est mise en œuvre de la même manière qu'un index unique - un index est nécessaire pour répondre efficacement à l'exigence d'appliquer la contrainte. Même si l'index est créé à la suite d'une contrainte UNIQUE, le planificateur de requêtes peut l'utiliser comme n'importe quel autre index s'il le considère comme le meilleur moyen de traiter une requête donnée.
Ainsi, pour une base de données prenant en charge les deux fonctionnalités, le choix de l’utilisation dépendra souvent du style et de la cohérence souhaités.
Si vous envisagez d’utiliser l’index comme index (c’est-à-dire que votre code peut s’appuyer sur la recherche / le tri / le filtrage sur ce champ pour être rapide), j’utiliserais explicitement un index unique (et commenter la source) plutôt qu’une contrainte pour le faire. clear - de cette façon, si l'exigence d'unicité est modifiée dans une révision ultérieure de l'application, vous (ou un autre codeur) saurez vous assurer qu'un index non unique est mis à la place de l'index unique (le seul fait de supprimer une contrainte unique aurait pour effet de supprimer l'index complètement). De plus, un index spécifique peut être nommé dans un indice (c’est-à-dire WITH (INDEX (ix_index_name))), ce qui, selon moi, n’est pas le cas pour l’index créé en arrière-plan pour gérer l’unicité, car il est peu probable que vous connaissiez son nom.
De même, si vous devez uniquement imposer l'unicité en tant que règle métier plutôt que le champ devant faire l'objet d'une recherche ou d'un tri, utilisez la contrainte, afin de rendre l'utilisation prévue plus évidente lorsque quelqu'un d'autre examine votre définition de table.
Notez que si vous utilisez à la fois une contrainte unique et un index unique sur le même champ, la base de données ne sera pas assez claire pour voir la duplication. Vous obtiendrez ainsi deux index qui consommeront de l'espace supplémentaire et ralentiront les insertions / mises à jour de lignes.
la source
CREATE TABLE #T(X INT CONSTRAINT PK PRIMARY KEY NONCLUSTERED);SELECT * FROM #T WITH(INDEX(PK)) WHERE X = 1
. Les index peuvent être plus flexibles dans la mesure où les contraintes ne supportent pas toutes les options d'index telles que lesINCLUDE
colonnes d ou les index filtrés.Outre les points abordés dans d’autres réponses, voici quelques différences essentielles entre les deux.
Remarque: Les messages d'erreur proviennent de SQL Server 2012.
les erreurs
La violation d'une contrainte unique renvoie l'erreur 2627.
La violation d'un index unique renvoie l'erreur 2601.
Désactiver
Une contrainte unique ne peut pas être désactivée.
Mais l'index unique derrière une contrainte de clé primaire ou une contrainte unique peut être désactivé, de même que tout index unique. Pointe du chapeau Brain2000.
Notez l'avertissement habituel selon lequel la désactivation d'un index en cluster rend les données inaccessibles.
Les options
Des contraintes uniques prennent en charge des options d'indexation telles que
FILLFACTOR
etIGNORE_DUP_KEY
, bien que cela n'ait pas été le cas pour toutes les versions de SQL Server.Colonnes Incluses
Les index non clusterisés peuvent inclure des colonnes non indexées (appelé index couvrant, il s'agit d'une amélioration majeure des performances). Les index derrière les contraintes PRIMARY KEY et UNIQUE ne peuvent pas inclure de colonnes. Hat-tip @ypercube.
Filtration
Une contrainte unique ne peut pas être filtrée.
Un index unique peut être filtré.
Contraintes de clé étrangère
Une contrainte de clé étrangère ne peut pas référencer un index unique filtré, bien qu'elle puisse référencer un index unique non filtré (je pense que cela a été ajouté dans SQL Server 2005).
Appellation
Lors de la création d'une contrainte, la spécification d'un nom de contrainte est facultative (pour les cinq types de contraintes). Si vous ne spécifiez pas de nom, MSSQL en générera un pour vous.
Lors de la création d'index, vous devez spécifier un nom.
Chapeau-pointe @ i-one.
Liens
http://technet.microsoft.com/en-us/library/aa224827(v=SQL.80).aspx
http://technet.microsoft.com/en-us/library/ms177456.aspx
la source
Pour citer MSDN en tant que source faisant autorité:
Et...
Autre dans: https://technet.microsoft.com/en-us/library/aa224827%28v=sql.80%29.aspx
la source
L'une des principales différences entre une contrainte unique et un index unique réside dans le fait qu'une contrainte de clé étrangère sur une autre table peut référencer des colonnes qui constituent une contrainte unique. Ce n'est pas vrai pour les index uniques. De plus, des contraintes uniques sont définies dans le cadre de la norme ANSI, contrairement aux index. Enfin, on considère que la contrainte unique réside dans le domaine de la conception de bases de données logiques (qui peut être implémentée différemment par différents moteurs de base de données) alors que l’index est l’aspect physique. Par conséquent, la contrainte unique est plus déclarative. Je préférerais une contrainte unique dans presque tous les cas.
la source
Dans Oracle, une différence majeure est que vous pouvez créer un index unique par fonction, ce qui n'est pas réalisable avec des contraintes uniques:
Par exemple
Donc, ce
fk_xyz
n’est unique que pour les disques qui ontamount != 0
.la source
WHERE
clause.CREATE UNIQUE NONCLUSTERED INDEX P4_U ON DBO.P4 ( PID ) WHERE TXT = 'qwert' ;
La contrainte UNIQUE est préférable à l'index UNIQUE. Lorsque la contrainte n'est pas unique, vous devez utiliser un index standard ou non unique. La contrainte est également un autre type d'index. Index 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.
la source