Как сохранить исторические детали модификации в базе данных (журнал аудита) - PullRequest
2 голосов
/ 27 марта 2010

Я разработчик J2EE, и мы используем отображение гибернации с базой данных PostgreSQL.

Мы должны отслеживать любые изменения, происходящие в базе данных, другими словами, все предыдущие и текущие значения любого поля должны быть сохранены. Каждое поле может быть любого типа (bytea, int, char ...)

С простой таблицей это легко, но у нас график объектов сложнее.

Таким образом, мы имеем, говоря с точки зрения UML, график объектов, которые должны храниться в базе данных при каждом изменении и пользователя.

Любая идея или шаблон, как это сделать?

Ответы [ 2 ]

1 голос
/ 28 марта 2010

Текущие реализации РСУБД не очень хороши в обработке временных данных. Это одна из причин, почему ведение отдельных журнальных таблиц с помощью триггеров является обычным подходом. (Другое заключается в том, что контрольные журналы часто имеют разные варианты использования для обычных данных, а их наличие в отдельных таблицах облегчает управление доступом к ним). Oracle делает довольно хитрую работу, пряча сантехнику в своем продукте Total Recall , но, будучи Oracle, она взимает за это $$$.

Скотт Бэйли опубликовал презентацию временных данных в PostgreSQL. Увы, это не поможет вам сейчас, но кажется, что некоторые функции, запланированные для 8.5 и 8.6, позволят прозрачное хранение данных, связанных со временем. Узнайте больше .

1 голос
/ 27 марта 2010

Обычный способ сделать это - хранить версии объектов.

Если добавить «версию» и «удаленное» поле к каждой таблице, в которой вы хотите сохранить контрольный журнал, тогда вместо выполнения обычных обновлений и удалений выполните следующие правила:

  • Вставить - установите номер версии на 0 и вставьте как обычно.
  • Обновление - увеличьте номер версии и вставьте вместо него.
  • Удалить - увеличить номер версии, установить для удаленного поля значение true и вместо этого выполнить вставку.
  • Получить - Получить запись с наибольшим номером версии и вернуть ее.

Если вы следуете этому шаблону, то при каждом обновлении вы будете создавать новую запись, а не перезаписывать старые данные, поэтому вы всегда сможете отслеживать и видеть все старые объекты.

Это будет работать точно так же для графиков объектов, просто добавьте новые поля в каждую таблицу в графе объектов и обработайте каждую вставку / обновление / удаление для каждой таблицы, как описано выше.

Если вам нужно знать, какой пользователь внес изменения, просто добавьте также поле «ModifiedBy».

(Вы можете выполнить эту обработку в своем коде слоя DA, или, если хотите, можете использовать триггеры базы данных, чтобы перехватывать ваши вызовы обновления / удаления / получения и повторно обрабатывать их в соответствии с правилами.)

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

...