Ajoutez une colonne calculée persistante qui combine les 18 clés, puis créez un index unique sur la colonne calculée:
alter table t add all_keys as c1+c2+c3+...+c18 persisted;
create unique index i18 on t (all_keys);
Voir Création d'index sur des colonnes calculées .
Une autre approche consiste à créer une vue indexée:
create view v
with schemabinding
as select c1+c2+c3+...+c18 as all_keys
from dbo.t;
create unique clustered index c18 on v(all_keys);
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:
create table t (
c1 char(3), c2 char(3), c3 char(3), c4 char(3),
c5 char(3), c6 char(3), c7 char(3), c8 char(3),
c9 char(3), c10 char(3), c11 char(3), c12 char(3),
c13 char(3), c14 char(3), c15 char(3), c16 char(3),
c17 char(3), c18 char(3), c19 char(3), c20 char(3),
constraint unq unique
(c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,c16,c17,c18));
go
Msg 1904, Level 16, State 1, Line 3
The index '' on table 't' has 18 column names in index key list.
The maximum limit for index or statistics key column list is 16.
Msg 1750, Level 16, State 0, Line 3
Could not create constraint. See previous errors.
Cependant, la création de la contrainte sur une colonne calculée persistante fonctionne:
create table t (
c1 char(3), c2 char(3), c3 char(3), c4 char(3),
c5 char(3), c6 char(3), c7 char(3), c8 char(3),
c9 char(3), c10 char(3), c11 char(3), c12 char(3),
c13 char(3), c14 char(3), c15 char(3), c16 char(3),
c17 char(3), c18 char(3), c19 char(3), c20 char(3),
all_c as
c1+c2+c3+c4+c5+c6+c7+c8+c9+c10+c11+
c12+c13+c14+c15+c16+c17+c18
persisted
constraint unq unique (all_c));
go
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 .