Столбцы, включенные в уникальный некластеризованный индекс, не являются частью ограничения UNIQUE
Пересказ статьи Greg Dodd. Included Columns on Unique Non-Clustered Indexes are not part of the Unique Constraint
Сегодня мне потребовалось добавить в таблицу ограничение уникальности (UNIQUE). Мы могли бы просто добавить ограничение, но данные, для которых я хочу добавить ограничение, уже были проиндексированы. Могу я просто сделать уникальный индекс, и покончить с этим? Давайте выясним это при помощи следующей таблицы:
CREATE TABLE Greg
(
ID INT PRIMARY KEY IDENTITY(1, 1),
Col1 INT NOT NULL,
Col2 INT NOT NULL,
IncludedValue VARCHAR(5) NULL,
NotIncludedValue1 VARCHAR(MAX) NULL,
NotIncludedValue2 VARCHAR(MAX) NULL
)
Очень простая таблица. Допустим, я часто выполняю поиск по Col1 и Col2 и хочу найти значение IncludedValue. Например, так:
SELECT Greg.IncludedValue
FROM Greg
WHERE Greg.Col1 = 1
AND Greg.Col2 = 2
Чтобы поиск выполнялся быстрее, я могу создать индекс на моей таблице:
CREATE NONCLUSTERED INDEX Col1Col2_Incldues
ON Greg (Col1, Col2)
INCLUDE (IncludedValue)
Прекрасно! Все работает хорошо, я могу выполнить Index Seek и вернуть IncludedValue. Бизнес-модель подразумевает, что вы знаете об уникальности комбинации Col1 и Col2. Как обеспечить поддержку уникальности на уровне базы данных? Вы можете добавить ограничение, но можно ли просто сделать этот индекс уникальным? Давайте создадим его и выясним:
CREATE UNIQUE NONCLUSTERED INDEX Col1Col2_Incldues_Unique
ON Greg (Col1, Col2)
INCLUDE (IncludedValue)
Теперь вставим запись:
INSERT INTO Greg (Col1, Col2, IncludedValue)
VALUES
( 1,
1,
'1st'
)
Что произойдет, если я выполню следующую команду? Позволят ли мне вставить запись, если IncludedValue будет другим, или запись будет блокироваться, поскольку Col1 и Col2 те же самые?
INSERT INTO Greg (Col1, Col2, IncludedValue)
VALUES
( 1,
1,
'2nd'
)
Догадаетесь? Или посмотрите ниже.
SQL блокирует запись.
Ключ индекса - вот что проверяется на уникальность. Включенные столбцы не проверяются.
Лучше ли это, чем ограничение UNIQUE? Не лучше и не хуже, это каждом случае точно то, что должно делать ограничение уникальности! Из документации:
Ядро базы данных автоматически создает УНИКАЛЬНЫЙ индекс для поддержки уникальности, требуемого ограничением UNIQUE.
База данных так или иначе создала бы этот индекс, просто без моего включенного столбца. Поэтому, если вы уже имеете индекс с всеми уникальными столбцами, то вы можете расширить существующий индекс, чтобы он содержал уникальные значения в ключе индекса, и сделать этот индекс уникальным вместо того, чтобы SQL добавил другой индекс.
Обратные ссылки
Автор не разрешил комментировать эту запись
Комментарии
Показывать комментарии Как список | Древовидной структурой