Уникальное противопоставление Postgres игнорирует нулевые значения, но Rails проходит - PullRequest
0 голосов
/ 12 июня 2018

У меня есть уникальный индекс в моей базе данных postgres в таблице participations, например,

"participation_uniqueness" UNIQUE, btree (event_id, firstname, lastname, email)

Это прекрасно работает, за исключением того, что если одно из полей равно nil, его в основном игнорируют:

event_id |имя |фамилия |Эл. адрес1982 |Джон |Доу |john@doe.de1982 |Ганс |Доу |john@doe.de1982 |ноль |ноль |john@doe.de1982 |ноль |ноль |john@doe.de

Я хочу, чтобы ограничение уникальности также применялось, если значение равно нулю, поэтому последняя запись в приведенной выше таблице примера НЕ должна быть возможной, поскольку она противоречит ограничению уникальности.

В Rails я мог бы просто добавить это как метод проверки к моей модели

validates_uniqueness_of :email, scope: [:event_id, :firstname, :lastname]

Мне интересно, почему эта проверка рассматривает NULL для проверок уникальности, но SQL делаетне?

Изучая эту тему, я понимаю, что это стандарт SQL, так как NULL интерпретируется как «недостающая информация», и вы не можете сравнить недостающую информацию друг с другом.

Однако с логической точки зрениязрения это не имеет смысла для меня.Я хочу, чтобы вставки БД в этом случае потерпели неудачу.Как я могу достичь этого, не применяя грязные обходные пути, опубликованные здесь, например https://www.pgrs.net/2008/01/11/postgresql-allows-duplicate-nulls-in-unique-columns/

1 Ответ

0 голосов
/ 12 июня 2018

Существует потенциальный ответ здесь с использованием частичных индексов.

CREATE UNIQUE INDEX ab_c_null_idx ON my_table (a, b) WHERE c IS NULL;

Rails ведет себя по-разному, потому что он делает гораздо больше в валидаторе уникальности .Это не просто выполнение запроса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...