Запрет повторов и обязательность заполнения — отдельные правила. Объясняем на простом примере, как PostgreSQL проверяет уникальность при неизвестном значении.
Уникальность ещё не означает заполненность
Представим условный каталог оборудования. У каждого предмета есть внутренняя карточка, а заводской номер заполняют после приёмки. Команда хочет запретить два одинаковых известных заводских номера, но разрешить создать несколько карточек до завершения проверки. Поэтому формулировка «поле уникальное» оставляет важный вопрос: что делать, пока номер неизвестен?
В SQL, языке работы с данными, отсутствие известного значения может обозначаться NULL. Это специальный признак, который нужно отличать от числа ноль и от записанной строки нулевой длины. Базовый смысл разобран в статье об отсутствии значения. Здесь рассмотрим более узкую задачу: какое правило повторов действует, когда такие пропуски встречаются в поле с ограничением уникальности.
В PostgreSQL важно выбранное поведение проверки
Согласно документации PostgreSQL об ограничениях, при стандартном поведении два NULL не считаются равными для проверки уникальности. Поэтому уникальное поле может содержать несколько строк с таким признаком. Это не означает, что база установила различие между неизвестными заводскими номерами: она применяет определённое правило контроля.
Для нашего каталога это подходит на этапе приёмки: известный номер не должен повторяться, а несколько ещё не проверенных предметов могут существовать одновременно. Но назвать такую настройку безусловно правильной нельзя. Если по смыслу проекта допускается лишь одна незаполненная карточка, необходимо отдельно выразить именно это требование и согласовать его с владельцем процесса.
Запрет пропусков задаётся отдельно
В той же документации обязательность значения описана самостоятельным ограничением. Можно потребовать и заполненность, и отсутствие повторов. Тогда наш каталог должен будет получать заводской номер до сохранения карточки либо использовать другой порядок приёмки. Это решение меняет рабочий процесс, поэтому его нельзя принимать только по названию технического ограничения.
Предложим для обсуждения три вымышленные карточки: у первой номер известен, у двух других он ещё не установлен. При допустимых пропусках все три могут храниться одновременно. При обязательном заполнении две карточки потребуют дополнительных действий. В обоих случаях надо отдельно ответить, может ли повториться уже известный номер. Эти вопросы удобно обсуждать раздельно, чтобы не спрятать одно требование внутри другого.
У составного правила есть дополнительная тонкость
Иногда уникальность относится к сочетанию нескольких полей. В нашем примере заводской номер может проверяться вместе с производителем: разные производители используют собственную нумерацию. В описании уникальных индексов PostgreSQL указано, что проверка нескольких столбцов отклоняет повтор, когда совпадают все проверяемые значения. Поведение пропусков при этом тоже имеет значение.
PostgreSQL позволяет выбрать режим, в котором NULL для такой проверки рассматриваются как равные. Синтаксис здесь не нужен: важно уметь поставить вопрос специалисту о фактически выбранном режиме. Не переносите предположение из одного проекта в другой. Документация отдельно предупреждает, что поведение неизвестных значений при уникальности может различаться между системами управления базами данных.
Проверять нужно смысл, а затем настройку
Для нашего каталога подготовим небольшой список ожидаемых случаев: повтор известного номера, два неизвестных номера, одинаковый номер у разных производителей, изменение пропуска на уже занятый номер. Рядом запишем желаемый результат каждого случая словами. Такой список не требует программирования и помогает обнаружить расхождение между договорённостью команды и фактической моделью хранения.
Уникальное поле само по себе не гарантирует, что две карточки относятся к разным физическим предметам. Для устойчивой связи записей полезно понимать назначение ключей. Продолжить знакомство с правилами хранения и проверки данных можно на курсе «SQL инженер». Начните с короткого требования: какие значения обязательны, какие повторы запрещены и что означает неизвестность в вашей задаче.


