Unique constraint
Unique Constraint на nullable полях в БД¶
Что будет, если в БД повесить на nullable поле БД констрейнт на уникальность и попытаться вставить несколько записей с null
в этом поле?
По стандарту SQL null
это не значение, это отсутствие значения. Поэтому с точки зрения БД (null = null) - fasle
и (null <> null) - false
и БД не считают, что несколько null
в одной колонке нарушают констрейнт уникальности.
В принципе, большинство разработчиков это понимают. Интересно же то, что это верно не для всех БД. Например, MSSQL Server отходит от стандарта, и в случае с unique constraint считает null
значением, и не дает вставить больше одной записи. Для того, чтобы воспроизвести поведение всех остальных БД на MSSQL необходимо воспользоваться дополнительным условием на индексе:
И то, эта конструкция появилась только с версии SQL Server 2008, до нее вам бы пришлось придумывать какие-нибудь костыли.
С составными индексами еще интереснее. Как поведет себя nullable поле в составном индексе?
Например, следующий код:
create table my_table (
A int not null,
B int not null,
C int null,
constraint u_constrainte unique (A, B, C)
);
insert into my_table (A, B, C) values (1, 2, 3);
insert into my_table (A, B, C) values (1, 2, null);
insert into my_table (A, B, C) values (1, 2, null);
Правильный ответ: зависит от БД. Стандарт SQL дает расплывчатую информацию, что будет в этом случае. На практике же, PostgreSQL без проблем выполнит все 3 insert
. А Oracle на третьем insert
будет жаловаться на нарушение констрейнта. При этом, если бы все 3 поля были nullable, то Oracle разрешил бы вставлять сколько угодно записей (null, null, null)
;