Прежде всего, необходимо добавить набор свойств для таблиц:
- Version - время последней модификации (также может быть автоинкремент счетчика вместо времени).
- LastModifiedBy - ссылка на пользователя, внесшего последнюю модификацию (если вы храните это).
Тогда у вас есть несколько вариантов хранения истории версий. Вы можете
Создайте новую таблицу для каждой из основных таблиц, для которой вы хотите сохранить историю. Эти таблицы истории будут иметь все те же поля, что и основная таблица, но первичные и внешние ключи не будут применяться. Для каждого внешнего ключа также сохраняется версия ссылочной записи в момент создания версии.
ИЛИ вы можете сериализовать все, что интересно о вашей сущности, и сохранить все эти сериализованные капли для всех объектов, которые вы хотите использовать в одной глобальной таблице истории (я лично предпочитаю первый подход).
Как вы заполняете свои таблицы истории? Через триггеры обновления и удаления.
- В триггере обновления для вашей сущности - скопировать все предыдущие значения в таблицу предыстории. Для каждого внешнего ключа - также копировать текущую версию ссылочного объекта.
- В триггере удаления - в основном делают то же самое.
Обратите внимание, что все больше и больше современных систем НЕ удаляют ничего. Они просто mark вещи как удалены. Если вы захотите следовать этому шаблону (который имеет несколько преимуществ), вместо удаления флажка IsDeleted вашим сущностям (конечно, вам придется отфильтровывать удаленные объекты повсюду).
Как вы просматриваете свою историю? Просто используйте таблицу истории, поскольку она имеет все те же свойства, что и основная таблица, - не должно быть проблемой. Но - при расширении внешних ключей - убедитесь, что ссылочная версия Version такая же, как и в вашей таблице истории. Если это не так - вам нужно перейти в таблицу «История» этого ссылочного объекта и получить значения там. Таким образом, вы всегда будете иметь снимок того, как объект выглядел в этот момент, включая все ссылки.
В дополнение ко всему выше - вы также можете восстановить состояние своей сущности в любой предыдущей версии.
Обратите внимание, что эта реализация, хотя и проста, может потреблять некоторое пространство, поскольку хранит моментальный снимок, а не только изменения. Если вы хотите просто сохранить изменения - в триггере обновления вы можете определить, какие поля были изменены, сериализовать их и сохранить в глобальной таблице истории. Таким образом, вы можете хотя бы показать в интерфейсе пользователя, что изменилось и кем (хотя у вас могут возникнуть проблемы с возвратом к какой-либо предыдущей версии).
Я добавлю щедрость, чтобы получить более подробный ответ: –
@AnynameDonotcare для каждой таблицы, в которой вы хотите сохранить историю: 1) добавить столбец версии (может быть время, может увеличивать счетчик). 2) добавить другую таблицу со всеми теми же свойствами, что и основная таблица (но лучше расширить внешние ключи). 3) Перед запуском обновления, если столбец версии изменился - скопируйте старые значения в эту таблицу версий. 4) Прибыль. – Evk
@ Evk: Я буду так благодарен, если бы вы могли добавить подробный ответ простым примером (с использованием 'EF') можно было бы использовать в качестве базы для корпоративного приложения (относительно действия удаления и связей mm) –