Selon la CREATE INDEX
documentation:
Jusqu'à 16 colonnes peuvent être combinées en une seule clé d'index composite.
Nous avons un tableau avec environ 18 colonnes qui doivent former une combinaison unique. Ce tableau n'est pas sensible aux performances - nous mettons rarement à jour les valeurs / insérer des enregistrements. Nous devons juste nous assurer d'éviter la duplication de nos enregistrements ... et nous avons pensé que nous pourrions imposer une simple contrainte d'unicité.
Des idées? Je suis prêt à éviter complètement l'index / la contrainte unique s'il existe une meilleure solution.
Réponses:
Ajoutez une colonne calculée persistante qui combine les 18 clés, puis créez un index unique sur la colonne calculée:
Voir Création d'index sur des colonnes calculées .
Une autre approche consiste à créer une vue indexée:
Voir Création de vues indexées .
Les deux approches permettent un agrégat de clé partiel: agrégat c1 + c2 + c3 comme k1, c4 + c5 + c6 comme k2 etc. puis indexer / créer une vue indexée sur (k1, k2, ...). Thia pourrait être bénéfique pour les balayages de plage (l'index peut être utilisé pour la recherche sur c1 + c2 + c3.
Bien sûr, toutes les
+
opérations dans mon exemple sont une agrégation de chaînes, l'opérateur réel à utiliser dépend des types de toutes ces colonnes (c'est-à-dire que vous devrez peut-être utiliser des transtypages explicites).PS. Comme les contraintes uniques sont appliquées par un index unique, toute restriction sur les index uniques s'appliquera également aux contraintes uniques:
Cependant, la création de la contrainte sur une colonne calculée persistante fonctionne:
De toute évidence, la colonne persistante consomme l'espace sur le disque, donc l'approche peut être mauvaise pour une très grande table. L'approche de la vue indexée n'a pas ce problème, elle consomme uniquement l'espace pour l' index , pas l'espace pour la colonne et l' index calculés .
la source
Je pense que vous feriez beaucoup mieux de placer votre vérification d'index unique sur une colonne calculée qui est générée en utilisant
HASHBYTES('MD5', ...)
la combinaison de vos 18 colonnes.la source
J'ai rencontré ce problème et mon DBA senior a suggéré d'utiliser une fonction de vérification d'unicité. Mes insertions sont relativement petites et peu fréquentes (~ 1000 lignes, insérées au début de chaque mois) et ma seule préoccupation est de faire respecter l'unicité.
@RBarryYoung, je n'ai pas encore de représentant pour commenter, mais j'ai eu des problèmes avec la solution HASHBYTES car l'un de mes types de données était un datetime, et j'ai commis l'erreur newbie (?) De ne pas fournir l'argument de style optionnel à mon Fonction CONVERT lors de la conversion en varchar. Sans le style, vous obtenez l'erreur suivante lorsque vous essayez d'ajouter les
PERSISTED UNIQUE NONCLUSTERED
contraintes:la source
Vous pouvez combiner certaines des valeurs afin de créer une nouvelle valeur unique et la stocker en plus des données actuelles.
Créez une fonction définie par l'utilisateur pour créer les nouvelles valeurs et un déclencheur pour remplir le champ lorsque des données sont ajoutées, vous n'avez donc pas beaucoup plus de temps pour gérer le champ.
La combinaison de deux ou trois de vos domaines vous mettrait sous la limite de 16.
la source
Vous pouvez utiliser un déclencheur pour
insert
/update
. Effectuez un regroupement sélectionné par vos colonnes avec une clause dehaving count(*) > 1
. Si cela revient non vide, annulez.la source
Voici ce que je ferais. Je créerais un déclencheur AFTER pour INSERT, UPDATE qui fait une
ROW_NUMBER ()
fonction et partitionne chacune des 18 colonnes uniques. Si le nombre maximal de lignes est supérieur à un, faites aROLLBACK
.la source