Совет дня №34
Банально, но все же: если какой-то атрибут уникален, нужно повесить на него уникальное ограничение. С ним физически невозможно добавить в базу дубликат. Многие разработчики проверяют уникальность вручную: если нет, то вставить, если есть, то ругнуться. Однажды запрос приходит от потребителя, который не в курсе этих заморочек, и получается дубль. Со временем на него ссылаются другие сущности, он обрастает связями. Когда дубль вскрывается, и все чешут голову — как же так получилось?
Удаление дубликата, обросшего связями — очень напряжная вещь. Нужно построить дерево ссылок, спланировать перенос, всех предупредить. Раздражает, что это тупая работа, которая не двигает вперед ни тебя, ни фирму. Просто слив времени из-за чужого косяка.
Похожая история случилась недавно на работе. Есть таблица с важными сущностями на двести штук. Кроме ключей, у них уникальные коды, которые производит внешняя система. Какой-то скрипт не проверил код на уникальность и добавил такую же. Долгое время использовались обе, и как теперь быть — непонятно.
Опытный разработчик знает, как исправить дубль; более опытный знает, как его не допустить.
При создании таблицы поле можно пометить словом unique. При этом Postgres
создаст уникальный btree-индекс на это поле. Заметим, что уникальность допускает
значения NULL, потому что они не равны друг другу. Если нулы запрещены, добавьте
в поле NOT NULL.
Можно задать свой уникальный индекс, при этом использовать не колонку, а выражение. Например, уникальность кода или почты нужно проверять без учета регистра и отбрасывая пустые символы по краям. Индекс может быть таким:
create unique index idx_user_email_u_btree
on users using btree
(trim(lower(email)))
После этого в базе не может быть емейлов "Ivan@test.com" и " iVan@TEST.com "
одновременно.
Уникальность можно повесить на поле JSON-документа. Если код находится где-то в глубине, индекс выглядит так:
create unique index idx_item_code_u_btree
on users using btree
(lower(data #>> '{attrs,path,to,code}'))
Следите за уникальностью. Добавить ее — дело пяти минут, исправлять последствия — пять дней.
Нашли ошибку? Выделите мышкой и нажмите Ctrl/⌘+Enter