Когда я должен использовать уникальное ограничение вместо уникального индекса?

dba.stackexchange https://dba.stackexchange.com/questions/144

Вопрос

Когда я хочу, чтобы столбец имел различные значения, я могу либо использовать ограничение

create table t1(
id int primary key,
code varchar(10) unique NULL
);
go

или я могу использовать уникальный индекс

create table t2(
id int primary key,
code varchar(10) NULL
);
go

create unique index I_t2 on t2(code);

Колонны с уникальными ограничениями, кажется, являются хорошими кандидатами для уникальных индексов.

Есть ли какие -либо известные причины для использования уникальных ограничений, а не использовать уникальные индексы?

Это было полезно?

Решение

Под капотом уникальное ограничение осуществляется так же, как уникальный индекс - необходим индекс для эффективного удовлетворения требования для обеспечения соблюдения ограничения. Даже если индекс создается в результате уникального ограничения, планировщик запросов может использовать его как любой другой индекс, если он видит его как лучший способ приблизиться к данному запросу.

Таким образом, для базы данных, которая поддерживает обе функции, выбор, которые можно использовать, часто сводится к предпочтительному стилю и последовательности.

Если вы планируете использовать индекс в качестве индекса (то есть ваш код может полагаться на поиск/сортировку/фильтрацию в этом поле, чтобы быть быстро Ясно - таким образом, если требование уникальности изменено в более позднем пересмотре приложения, которое вы (или какой -то другой кодер) узнаете, чтобы убедиться, что индекс, не являющийся университетом Индекс полностью). Также конкретный индекс может быть назван в индексе (т.е. с (index (ix_index_name)), который, я не думаю, является случаем для индекса, созданного за кулисами для управления уникальностью, поскольку вы вряд ли узнаете его имя.

Точно так же, если вам нужно только обеспечить уникальность как деловое правило, а не поле, которое нужно искать или использовать для сортировки, тогда я бы использовал ограничение, опять же, чтобы сделать предполагаемое использование более очевидным, когда кто -то еще смотрит на определение вашей таблицы.

Обратите внимание, что если вы используете как уникальное ограничение, так и уникальный индекс в том же поле, база данных не будет достаточно яркой, чтобы увидеть дублирование, поэтому вы получите два индекса, которые будут потреблять дополнительное пространство и замедлить вставки/обновления строк.

Другие советы

В дополнение к точкам в других ответах, вот некоторые ключевые различия между ними.

Примечание. Сообщения об ошибках от SQL Server 2012.

Ошибки

Нарушение уникального ограничения возвращает ошибку 2627.

Msg 2627, Level 14, State 1, Line 1
Violation of UNIQUE KEY constraint 'P1U_pk'. Cannot insert duplicate key in object 'dbo.P1U'. The duplicate key value is (1).
The statement has been terminated.

Нарушение уникального индекса возвращает ошибку 2601.

Msg 2601, Level 14, State 1, Line 1
Cannot insert duplicate key row in object 'dbo.P1' with unique index 'P1_u'. The duplicate key value is (1).
The statement has been terminated.

Отключение

Уникальное ограничение не может быть отключено.

Msg 11415, Level 16, State 1, Line 1
Object 'P1U_pk' cannot be disabled or enabled. This action applies only to foreign key and check constraints.
Msg 4916, Level 16, State 0, Line 1
Could not enable or disable the constraint. See previous errors.

Но уникальный индекс ограничения первичного ключа или уникального ограничения может быть отключено, как и любой уникальный индекс. Hat-Tip Brain2000.

ALTER INDEX P1_u ON dbo.P1 DISABLE ;

Обратите внимание на обычное предупреждение о том, что отключение кластерного индекса делает данные недоступными.

Опции

Уникальные ограничения поддержки вариантов индексации, такие как FILLFACTOR а также IGNORE_DUP_KEY, хотя это не имело место для всех версий SQL Server.

Включен столбцы

Не классифицированные индексы могут включать неиндексированные столбцы (называемые индексом покрытия, это основное повышение производительности). Индексы, лежащие в основе первичного ключа и уникальных ограничений, не могут включать столбцы. Hat-tip @ypercube.

Фильтрация

Уникальное ограничение не может быть отфильтровано.

Уникальный индекс может быть отфильтрован.

CREATE UNIQUE NONCLUSTERED INDEX Students6_DrivesLicence_u 
ON dbo.Students6( DriversLicenceNo ) WHERE DriversLicenceNo is not null ;

Ограничения иностранного ключа

Ограничение внешнего ключа не может ссылаться на фильтрованный уникальный индекс, хотя он может ссылаться на нефильтрованный уникальный индекс (я думаю, что это было добавлено в SQL Server 2005).

Именование

При создании ограничения указание имени ограничения является необязательным (для всех пяти типов ограничений). Если вы не указаете имя, то MSSQL сгенерирует его для вас.

CREATE TABLE dbo.T1 (
    TID int not null PRIMARY KEY
) ;
GO
CREATE TABLE dbo.T2 (
    TID int not null CONSTRAINT T2_pk PRIMARY KEY
) ;

При создании индексов вы должны указать имя.

Hat-tip @i-one.

Ссылки

http://technet.microsoft.com/en-us/library/aa224827(v=sql.80).aspx

http://technet.microsoft.com/en-us/library/ms177456.aspx

Цитировать MSDN в качестве авторитетного источника:

Нет существенных различий между созданием уникального ограничения и созданием уникального индекса, который не зависит от ограничений. Анкет Проверка данных происходит таким же образом, и оптимизатор запроса не различает уникальный индекс, созданный ограничением или созданным вручную. Однако создание уникального ограничения на столбце делает цель индекса ясным ... больше информации здесь

А также...

Двигатель базы данных автоматически создает уникальный индекс для обеспечения уникальности уникального ограничения. Следовательно, если предпринимается попытка вставить дубликатную строку, двигатель базы данных возвращает сообщение об ошибке, в котором говорится, что уникальное ограничение было нарушено и не добавляет строку в таблицу. Если не указан кластерный индекс, уникальный, не кластеризированный индекс создан по умолчанию для обеспечения уникального ограничения ... больше информации здесь

Другое в: https://technet.microsoft.com/en-us/library/aa224827%28v=sql.80%29.aspx

Одним из основных различий между уникальным ограничением и уникальным индексом является то, что ограничение внешнего ключа в другой таблице может ссылаться на столбцы, которые составляют уникальное ограничение. Это не верно для уникальных индексов. Кроме того, уникальные ограничения определяются как часть стандарта ANSI, а индексы - нет. Наконец, уникальное ограничение в том, что считается жить в сфере логического дизайна базы данных (которая может быть реализована по -разному различными двигателями БД), в то время как индекс является физическим аспектом. Следовательно, уникальное ограничение является более декларативным. Я бы предпочел уникальные ограничения практически во всех случаях.

В Oracle основное различие в том, что вы можете создать индекс Uniak, который не выполнится с уникальными ограничениями:

Например

create unique index ux_test on my_table (case when amount != 0 then fk_xyz end);

Так fk_xyz уникален только для записи, которая имеет amount != 0.

Уникальное ограничение предпочтительнее уникального индекса. Когда ограничение не является уникальным, вам нужно использовать обычный или не уникальный индекс. Ограничение также является еще одним типом индекса. Индекс используется для более быстрого доступа.

Уникальные индексы могут иметь там, где положения. Например, вы можете создавать индексы для каждого года на основе столбца даты

WHERE Sale_Date BETWEEN '2012-01-01' AND '2012-12-31'
Лицензировано под: CC-BY-SA с атрибуция
Не связан с dba.stackexchange
scroll top