2008-08-23 7 views
24

Каковы некоторые стратегии, с которыми люди добились успеха для ведения истории изменений данных в довольно сложной базе данных. Одно из приложений, которое я часто использую и разрабатываю, действительно может извлечь выгоду из более полного способа отслеживания изменений записей со временем. Например, в настоящее время записи могут иметь несколько временных меток и измененных полей пользователя, но в настоящее время у нас нет схемы регистрации нескольких изменений, например, если операция откат. В идеальном мире, можно было бы восстановить запись, как это было после каждого сохранения и т.д.Эффективная стратегия выхода из аудита/история изменений для приложений БД?

Некоторая информация о БД:

  • должен иметь способность расти тысячами записей в неделю
  • 50-60 столы
  • Основные revisioned таблицы могут иметь несколько миллионов записей каждый
  • Умеренное количество внешних ключей и индексов установить
  • Использование PostgreSQL 8.x
+0

Рассмотрите возможность использования [временной базы данных] (http://en.wikipedia.org/wiki/Temporal_database «Запись в Википедии»). – 2008-09-16 02:29:25

ответ

9

В прошлом я использовал триггеры для построения db update/insert/delete logging.

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

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

+8

Проблема с решением на уровне базы данных заключается в отсутствии бизнес-контекста для действия, т. Е. Вы не знаете, какой пользователь это сделал или что они делают. Большинство веб-приложений подключаются к своей базе данных, используя одно имя пользователя, поэтому имя пользователя, зарегистрированное в сети, не является именем пользователя, которое видит триггер. – 2008-12-02 11:00:36

+8

Andrew, любое решение на уровне базы данных вообще не является аудиторским тропом, поскольку оно не будет захватывать записи, не добавленные в графический интерфейс. Наши ловит конкретных пользователей, потому что все наши таблицы имеют последний_определенный столбец, а вставки, обновления и т. Д. Все отправляют person_id человека, делающего обновление, а не веб-именем пользователя. – HLGEM 2008-12-22 19:33:13

22

Одной стратегией, которую вы можете использовать, является MVCC, Multi-Value Concurrency Control. В этой схеме вы никогда не обновляете ни одну из ваших таблиц, вы просто вставляете, поддерживая номера версий для каждой записи. Это имеет то преимущество, что обеспечивает точную моментальную снимок с любого момента времени, а также полностью оборачивает проблемы блокировки обновлений, которые поражают многие базы данных.

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

+2

Как узнать, какая из них является текущей версией? С верхним 1 порядком по условию desc? @Eric Z Beard – 2015-08-24 15:19:52

10

Если вы используете Hibernate, взгляните на JBoss Envers. На домашней странице проекта:

Проект Envers призван обеспечить легкое управление устойчивыми классами JPA. Все, что вам нужно сделать, это аннотировать ваш постоянный класс или некоторые его свойства, которые вы хотите использовать, с помощью @Versioned. Для каждого объекта с версией будет создана таблица, в которой будет храниться история изменений, внесенных в объект. Затем вы можете получать и запрашивать исторические данные без особых усилий.

Это похоже на Eric's approach, но, вероятно, гораздо меньше усилий. Не знаю, какой язык/технология вы используете для доступа к базе данных.

4

Единственная проблема с использованием триггеров заключается в том, что он добавляет к служебным нагрузкам любой вставки/обновления/удаления. Для большей масштабируемости и производительности вы хотели бы свести транзакцию базы данных к минимуму. Аудит через триггеры увеличивает время, необходимое для выполнения транзакции, и в зависимости от объема может вызвать проблемы с производительностью.

Другой способ - изучить, предоставляет ли база данных любой способ добычи журналов «Повторить», как это имеет место в Oracle. Журналы повтора - это то, что использует база данных для воссоздания данных в случае ее отказа и требует восстановления.

3

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

Кроме того, вы можете улучшить производительность первичной базы данных, сохранив базу данных аудита в отдельном месте.

1

Я использую SQL Server, а не PostgreSQL, так что я не уверен, если это будет работать для вас или нет, но поп Риветт была большая статья о создании аудита здесь: Pop rivett's SQL Server FAQ No.5: Pop on the Audit Trail

Сборки аудит table, а затем создайте триггер для каждой таблицы, которую вы хотите проверить.

Подсказка: используйте Codesmith, чтобы создать триггеры.