Мы разрабатываем крупные приложения, связанные с бизнесом. Вы можете найти эти приложения, похожие на некоторые ERP, CRM и т. Д.
Теперь у нас есть требование, чтобы нам нужны все данные, которые вводится пользователем для версии.
Например: через какое-то время пользователь должен будет узнать, что такое история изменений конкретного заказа на поставку?
Я ищу очень общий обработчик версий (не жесткий), который может обрабатывать даже случаи, если некоторые атрибуты бизнес-данных будут изменены. Этот единственный обработчик управления версиями должен иметь возможность работать практически с любыми бизнес-объектами / данными.
Каким будет лучший дизайн программирования / базы данных для их обработки.
Любые идеи или мнения?
PS: Я добавил некоторые теги программирования, поскольку я хочу, чтобы программисты развлекали эту тему и давали свои идеи.
EDIT: Я ищу очень оптимизированный способ, несколько похожий на то, что у меня есть хранители различий, а не хранение объектов в сериализованном / демпинговом режиме.
Это может быть подходящее время для использования чисто функциональных ленивых структур данных.
В двух словах это требует запрета каких-либо мутирующих операций над вашими объектами, т. Е. Сделать все экземпляры объекта неизменными . Затем вы перепроектируете все операции, которые изменяют существующий объект, на создание нового экземпляра объекта на основе старого.
Например, пусть у вас есть экземпляр Order
который содержит список OrderItem
s, и вам нужно добавить в этот список определенный OrderItem
. В этом случае вы создаете новый экземпляр Order
, заменяя его список элементов новым списком, который, в свою очередь, создается путем OrderItem
нового OrderItem
в старый список.
Позвольте мне проиллюстрировать этот пример далее на фотографиях. Представьте себе хранилище объектов (пусть это будет ОЗУ или реляционная база данных, что угодно):
Адрес | Объект | Сделано -------- + -------------------- + -------------------- ---------------------- 1000 | список OrderItems | пустой конструктор списка 1001 | Заказать | Заказать конструктор, использует адрес 1000 ... 1300 | OrderItem | ... 1501 | список OrderItems | минусов от addr 1300 до addr 1000 1502 | Заказать | замените order_items в addr 1001 на addr 1501
Сама структура хранения данных таким образом настойчива (например, Крис Окасаки подробно описывает это в своей диссертации ). Вы можете восстановить любую версию объекта, просто следуя его истории создания; управление версиями становится тривиальным. Просто запомните главное: не мутируйте данные, вместо этого создавайте новые экземпляры.
Что-то похожее на Hibernate Envers – решение для проверки сущности, похоже, хорошо подходит для ваших требований.
Если вы не занимаетесь инвазивным (я вижу, что общий, как конкурирующий с инвазивным), я думаю, что ваш вариант состоит в полной сериализации. В каждой версии вы просто делаете снимок объекта и сериализуете его в соответствии с тем, что подходит.
Если вы были ограничены базой данных, например, просто сохраните ее с отметкой времени и возьмите самую последнюю метку времени как текущую. Однако я бы не стал думать об этом как о проблеме с базой данных. Вам разрешается сериализоваться вне системы для таких вещей, как частичные результаты, тестирование, здравомыслие и т. Д.
В основном вы должны иметь возможность сравнивать поля существующего объекта и нового объекта и сохранять различия.
Обычно это делается для высокочувствительных объектов, чтобы отслеживать количество изменений в этой конкретной строке / учетной записи. Было бы излишним, если бы это было сделано для всех таблиц. Различия могут сохраняться асинхронно в отдельной таблице истории, которая соответствует той же схеме онлайн-таблиц.
Мне приходилось делать что-то подобное в прошлом.
Я обнаружил, что самый простой способ, если начать с нуля, – добавить дополнительный столбец в таблицу данных объектов, в которой содержится индекс объекта замены. Если значение было равно нулю, я знал, что это была последняя версия. Это также означало, что объекты никогда не удалялись, хотя позже я добавил функционал, который позволил бы удалить прошлую историю.
Эффективно индекс становится номером версии рассматриваемого объекта, и любой запрос к БД для последней версии будет использовать квалификатор WHERE NextVersionIndex=0
.
Если не начать с нуля, это можно реализовать в живой системе, добавив дополнительную таблицу для хранения этих значений – индекс объекта, индекс предыдущей версии, индекс следующей версии.