Как стать автором
Обновить

Внешний ключ должен вести не на сущность, а на актуальную версию этой сущности

Время на прочтение1 мин
Количество просмотров3.1K
Всего голосов 13: ↑6 и ↓7-1
Комментарии14

Комментарии 14

НЛО прилетело и опубликовало эту надпись здесь
Я конечно извиняюсь, но статья выглядит как развёрнутый комментарий при ревью pull-request.
Если я вас правильно понял, вы пишете о том что так может выглядеть комментарий при отказе закатки сделанных изменений в систему контроля версий.
Нет, потому что на этапе приёма от программиста уже сделанной работы, поздно поднимать вопросы о необходимости переделки архитектуры системы. Если у тим-лида подобное происходит, значит он не справился с постановкой задач в начале работы.
Да, вы правильно поняли. Просто по факту, такие вещи, как описаны это принимается на этапе проектирования системы, если там такие требования есть.

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

Пример: банк, использующий наш софт, создан в 2005 году. Человек пришёл сегодня. Прописка у него в паспорте стоит в 2003 году. Улицу, указанную в прописке, переименовали в 2004 году.

Так что надо именно закачивать из ФИАС адреса со всеми хвостами их изменений, и когда пришёл клиент — ставить ссылку на то конкретное состояние его адреса, которое было в момент прописки. + Так можно попытаться поймать мошенников, у которых дата прописки не бьётся с актуальным на тот момент наименованием адресов.
Значит, такая логика справедливо именно в вашем случае, потому, что это ваша бизнес логика, чтобы данные крепились к состоянию за то самое время и не менялись.

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

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

Внешние ключи должны из документов указывать именно на объект.
Всё, что вы написали после слова «потом», мне не понятно. Смысл статьи именно в том, что все ссылки из документов продолжают указывать на ПРЕДЫДУЩЕЕ состояние компании. Только создаваемые новые договора, будут указывать на новое состояние.

По поводу вашего текста до слова «потом» — да, согласен, с объектами имеющими много маловажных атрибутов, в которых атрибуты обычно изменяются одиночно а не пакетно, уже не так удобно. Тут надо найти золотую середину. Но ведь часто при каждом update система настроена так, что сохраняет в таблице истории весь набор атрибутов — в этом случае предложенный мной метод однозначно более эффективен.
Так я не понимаю одновременно вашей проблемы, вот у вас была улица А, она переименовалась в улицу Б, значит это история записи А -> Б, вы отдельно храните атрибут имени, как свойство, связывая, вы указываете нужный атрибут, все

Когда улица меняется, она создается НОВАЯ, а не изменяется старая, но связка есть с старой, для «истории» и соотношения
Проблема — в офис банка пришёл клиент, в паспорте у него прописка на улице А.
Нужно сохранить эти данные в БД, не потеряв понимание, что А и Б это одна улица, но и не утратив информацию что в прописке клиента именно А а не Б.
При этом при каждой обработке документа недопустимо выполнять поиск в истории, нужно сохранить в БД его прописку именно со ссылкой на версию данных, а не искать потом по имени улицы что будет ресурсоёмко.

Статья написана максимально простым языком, странно что её можно не понять.
В общем случае, это неправильно. Например, в производственной программе карточка товара содержит поля «поставщик», «оперативный склад», и т.п.
Из конструкторской спецификации, по вашей логике, надо делать ссылку не на карточку, а на версию карточки в момент создания спецификации. После чего любые изменения атрибутов никак не отразятся на спецификации (например, мы этот товар храним теперь на другом складе или получаем от другого поставщика). Получается такая immutable схема, где, чтобы изменить атрибут в одном месте, нужно пересоздать все объекты в иерархии связей, ссылающиеся на это место…
При гарантийном случае, товар ремонтируется поставщиком, верно?

Значит, нам нельзя просто присваивать в «карточку товара» (не вполне понимаю что это) нового поставщика. Иначе мы будем отсылать товар, произведённый одним поставщиком, на ремонт другому поставщику.

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

Часть проблем подняты выше решается версионированием, часть использованием Value Object и прочей дубликацией

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории