Добавьте постоянный вычисляемый столбец, который объединяет 18 ключей, затем создайте уникальный индекс для вычисляемого столбца:
alter table t add all_keys as c1+c2+c3+...+c18 persisted;
create unique index i18 on t (all_keys);
См. Создание индексов для вычисляемых столбцов .
Другой подход заключается в создании индексированного представления:
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);
См. Создание индексированных представлений .
Оба подхода допускают частичную агрегацию ключей: агрегат c1 + c2 + c3 как k1, c4 + c5 + c6 как k2 и т. Д., Затем индексирование / создание индексированного представления (k1, k2, ...). Это может быть полезно для сканирования диапазона (индекс может использоваться для поиска по c1 + c2 + c3.
Конечно, все +
операции в моем примере являются агрегацией строк, фактический используемый оператор зависит от типов всех этих столбцов (т. Е. Вам, возможно, придется использовать явное приведение).
PS. Так как уникальные ограничения применяются уникальным индексом, любое ограничение уникальных индексов будет применяться и к уникальным ограничениям:
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.
Однако создание ограничения для сохраняемого вычисляемого столбца работает:
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
Очевидно, что постоянный столбец занимает место на диске, поэтому подход может быть плох для очень большой таблицы. Подход с индексированным представлением не имеет этой проблемы, он только использует пространство для индекса , а не пространство для вычисляемого столбца и индекса.