АналитикаСистемный анализСистемный аналитик

Зачем в модели данных разделять технический идентификатор сущности и её бизнес ключ?

Зачем в модели данных разделять технический идентификатор сущности и её бизнес-ключ?

Проходите собеседования с ИИ помощником Hintsage

Краткий ответ

Технический идентификатор нужен как стабильная внутренняя ссылка на запись, а бизнес-ключ — для идентификации сущности по правилам предметной области. Их разделение позволяет изменять бизнес-атрибуты без каскадного обновления связей и не смешивать технические детали хранения с бизнес-смыслом.

Бизнес-ключ при этом обычно должен иметь ограничение уникальности, а технический идентификатор — оставаться неизменным на протяжении жизненного цикла записи.

Исторический контекст

В ранних и небольших системах естественный атрибут часто использовали одновременно как идентификатор записи и как бизнес-признак: например, номер договора или адрес электронной почты. Это казалось простым, пока такие значения не потребовалось изменить, переиспользовать или связать с несколькими процессами.

Разделение стало практикой при усложнении моделей данных и появлении большого числа внешних связей. Оно решает проблему нестабильных бизнес-правил, не превращая изменение атрибута предметной области в миграцию всех зависимых ссылок.

Постановка проблемы

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

Если же бизнес-ключ не ограничить уникальностью, появятся две записи с одинаковым номером договора. Тогда поиск по бизнес-правилу станет неоднозначным, а технический идентификатор сам по себе не защитит систему от логической ошибки.

Подробное решение

В модели вводят отдельный неизменяемый технический идентификатор, например внутренний идентификатор записи. Все связи между таблицами и сущностями строят по нему. Бизнес-ключ хранится отдельным атрибутом и защищается уникальным ограничением в пределах нужной области действия.

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

Изменение бизнес-ключа тогда не меняет идентичность самой сущности: обновляется один атрибут, а внутренние связи остаются прежними. При этом внешние API не обязаны раскрывать технический идентификатор: наружу можно отдавать бизнес-ключ или отдельный публичный идентификатор, если внутренний ключ раскрывать нежелательно.

У подхода есть компромиссы. Появляются дополнительные поля, индексы и необходимость поддерживать уникальность, а неправильный выбор области уникальности может блокировать допустимые операции. Кроме того, технический идентификатор не отменяет требований к формату, проверке и жизненному циклу бизнес-ключа.

Ситуация из практики

В системе логистики код маршрута сначала считался уникальным и использовался как ключ во всех связанных сущностях. Позже выяснилось, что после закрытия маршрута тот же код может быть выдан повторно в новом операционном периоде.

Рассматривались два варианта. Первый — сохранять код маршрута первичным ключом и добавлять период в каждый внешний ключ: это сохраняло видимую структуру, но усложняло все связи и миграции. Второй — ввести стабильный внутренний идентификатор, а уникальность кода задать как составную: код плюс операционный период.

Выбрали второй вариант. Связи стали ссылаться на внутренний идентификатор, а бизнес-правило повторного использования кода выражалось отдельно и явно. В результате изменение кода и повторное использование его в другом периоде не приводили к перепривязке исторических грузов и документов.

Что кандидаты часто упускают

  1. Достаточно ли сделать бизнес-ключ уникальным на уровне приложения?

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

  1. Нужно ли всегда использовать искусственный технический идентификатор?

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

  1. Почему нельзя просто скрыть технический идентификатор и считать задачу решённой?

Скрытие в API не устраняет проблему модели. Внутренние связи всё равно должны опираться на стабильную идентичность, а бизнес-ключ — иметь ясные правила уникальности, изменения и повторного использования. Кроме того, внешним потребителям может потребоваться стабильный публичный идентификатор, который не совпадает ни с внутренним ключом, ни с изменяемым бизнес-атрибутом.