Выбор ответа Senior Проектирование и нормализация обновлено

Уникальность с мягким удалением

Вопрос

Пользователей не удаляют, а ставят deleted_at. Нужно, чтобы email был уникален среди активных, но удалённый email можно было зарегистрировать снова. Что сделать?

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: CREATE UNIQUE INDEX ON users (email) WHERE deletedat IS NULL. Частичный уникальный индекс проверяет уникальность только среди строк, подходящих под условие, то есть среди активных.

Варианты ответа

  1. UNIQUE (email, deleted_at) на таблице users
  2. CREATE UNIQUE INDEX ON users (email) WHERE deleted_at IS NULLправильный ответ
  3. UNIQUE (email) и при удалении ничего не менять
  4. Проверять уникальность в коде перед вставкой в транзакции

Разбор

Частичный уникальный индекс проверяет уникальность только среди строк, подходящих под условие, то есть среди активных. UNIQUE (email, deleted_at) не работает: у всех активных deleted_at равен NULL, а NULL в уникальном ограничении по умолчанию не считаются равными, и дубли активных пройдут. Обычный UNIQUE запретит повторную регистрацию. Проверка в коде даёт гонку.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.