Возьмем некоторую сущность модели данных, экземпляры которой идентифицируются бизнес-ключом. Бизнес-ключ - это код или номер, который известен конечным пользоватлям системы (представлен в пользовательском интерфейсе) и используется в коммуникациях. Например, артикул товара, код подразделения компании, табельный номер сотрудника. Когда один сотрудник передает другому список товаров, он передает список артикулов. Когда подразделение компании заводит заявку на обслуживание, оно указывает код подразделения; этот же код подразделения фигурирует в копроративных отчетах.
Бизнес-ключ, как правило, имеется у справочников (страны, типы заказа, ...), ресурсных сущностей (товар, поставщик, ...) и операционных сущностей (заказ, промо-акция, ...). Другие сущности (конфигурации, бизнес-транзакции) используют внешние бизнес-ключи как часть собственного уникального ключа.
Бывает, что бизнес-ключ изменяется пользователем.
Изменение бизнес-ключа оправдано, если была сделана ошибка при его первоначальном вводе. Мог быть нарушен формат кода или введено неправильное значение. Само собой, что ручной ввод бизнес-ключей разрешается только привилегированным пользователям, которые осознают ответственность, связанную с вводом бизнес-ключа, и потому семь раз отмерят, прежде чем резать. Но и на старуху бывает проруха. Не ошибается тот, кто не пьет шампанского.
Но если ошибка замечена и исправлена быстро, какая в том беда? А вот какая.
Бизнес-ключ в корпоративной модели данных является уникальным идентификатором экземпляра бизнес-сущности, и в силу этого используется не в одной только системе, куда его вводит пользователь, но в разных системах компании. Системы интегрированы при помощи сообщений об изменениях, отправляемых системой-источником, и получаемых и обрабатываемых системами-приемниками.
Предположим, есть бизнес-сущность Товар
с бизнес-ключом Артикул
и описательным атрибутом Название
. Необходимо ввести в систему данные о товаре с артикулом "ABC"
и названием "Шар голубой"
.
При вводе данных пользователь допустил ошибку и ввел товар с неправильным артикулом "ABB"
и правильным названием "Шар голубой"
. Система отправляет подписчикам сообщение об изменении товара {"операция": "создание", "артикул": "ABB", "название": "Шар голубой"}
. Другая система получает это сообщение и создает в своей таблице запись о товаре с артикулом "ABB"
.
Между тем пользователь исправляет ошибку и меняет артикул уже введенного товара с "ABB"
на "ABC"
. Теперь и артикул и название товара в первичной системе правильные, и система отправляет сообщение об изменении {"операция": "изменение", "артикул": "ABC", "название": "Шар голубой"}
. Другая система, получив это сообщение, пытается обновить в своей таблице товар с артикулом "ABC"
- и терпит неудачу, потому что строки с таким значением артикула в ее таблице нет.
Как справиться с такой ситуацией, не нагружая модель данных (и сообщения в шине данных) дополнительным идентификационным кодом, который бы не изменялся при изменении бизнес-ключа? Таким кодом мог бы быть первичный ключ таблицы с товарами из системы-источника, который по определению неизменен в течение всего жизненного цикла строки. Однако, он ничего не говорит пользователям, решая чисто техническую задачу в БД, и, таким образом, не дает оснований для распространения его в другие системы.
Решить проблему можно, приняв, что поле с бизнес-ключом в сообщении всегда содержит значение бизнес-ключа до его изменения, а новое значение ключа передается в необязательном поле "новый_артикул"
. Это поле будет добавляться в сообщение системой-источником только в случае изменения артикула товара.
Тогда первое сообщение после ошибочного ввода данных пользоватлем будет таким же, как и раньше, {"операция": "создание", "артикул": "ABB", "название": "Шар голубой"}
, и система-получатель создаст в своей таблице товар с артикулом "ABB"
. А второе сообщение, после исправления пользователем артикула, будет таким: {"операция": "изменение", "артикул": "ABB", "название": "Шар голубой", "новый_артикул": "ABC"}
. Система-получаталь обнаружит в сообщении "новый_артикул"
со значением "ABC"
и обновит в строке таблицы с артикулом "ABB"
не только название товара, но и сам артикул - на новое значение "ABC"
.
Может ли потенциально изменяемый бизнес-ключ в системе-источнике или системе-приемнике быть первичным ключом таблицы?
По-хорошему, не должен.
Но и из хороших правил встречаются исключения. Например, если мы говорим о справочнике, то код статьи справочника удобно иметь в качестве первичного ключа и, следовательно, в качестве внешних ключей в дочерних таблицах, - это позволяет избежать соединений с родительской таблицей при запросах дочерних таблиц по ключу справочника. И чем сложнее запрос, тем целесообразней избегать лишних соединений.
Об изменении значения первичного ключа будет отдельный пост.
Комментариев нет:
Отправить комментарий