Agregue una columna calculada persistente que combine las 18 claves, luego cree un índice único en la columna calculada:
alter table t add all_keys as c1+c2+c3+...+c18 persisted;
create unique index i18 on t (all_keys);
Consulte Crear índices en columnas calculadas .
Otro enfoque es crear una vista indizada:
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);
Consulte Crear vistas indizadas .
Ambos enfoques permiten un agregado clave parcial: agregado c1 + c2 + c3 como k1, c4 + c5 + c6 como k2, etc. luego indexar / crear una vista indexada en (k1, k2, ...). Thia podría ser beneficioso para los escaneos de rango (el índice se puede usar para buscar en c1 + c2 + c3.
Por supuesto, todas las +
operaciones en mi ejemplo son agregación de cadenas, el operador real a usar depende de los tipos de todas esas columnas (es decir, puede que tenga que usar conversiones explícitas).
PD. Como las restricciones únicas se aplican mediante un índice único, cualquier restricción en los índices únicos se aplicará también a las restricciones únicas:
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.
Sin embargo, crear la restricción en una columna computada persistente funciona:
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
Obviamente, la columna persistente consume el espacio en el disco, por lo que el enfoque puede ser malo para una tabla muy grande. El enfoque de vista indexada no tiene este problema, solo consume el espacio para el índice , no el espacio para la columna y el índice calculados .