Это лучший подход к созданию контрольного журнала? - PullRequest
3 голосов
/ 03 апреля 2009

Я пытаюсь создать некоторую функциональность, которая хранит контрольный журнал того, как данные в данной пользовательской форме менялись с течением времени, с датой аудита у подножия этой страницы. Например:

02/04/09 21:49 Имя изменено с "Том" на "Крис".

Я делаю это, сохраняя данные в текущем формате в сеансе, а затем сохраняю, проверяя, есть ли различия в сохраняемых данных. Если есть, я сохраняю данные, как это было до последнего редактирования в таблице, называемой историей, и сохраняю новые значения в текущей пользовательской таблице.

Это лучший подход?

Ответы [ 6 ]

11 голосов
/ 03 апреля 2009

Я не уверен, что существует один «лучший подход», так много переменных, которые необходимо учитывать, в том числе, насколько далеко вы находитесь на пути разработки.

Проработав решения для аудита на основе кода и db-trigger, я перечислил некоторые комментарии ниже; Я надеюсь, что вы можете увидеть, где вы находитесь (с точки зрения развития), могут повлиять на эти проблемы:

  • Если вам нужно сопоставить пользователя, который изменил данные (что вы обычно делаете), то триггерам БД потребуется каким-то образом получить эту информацию. Не невозможно, но больше работы и несколько способов подойти к этому (дБ выполняет пользовательский запрос, общий пользовательский столбец в каждой таблице и т. Д.)
  • Если вы используете триггеры БД и полагаетесь на количество затронутых строк, возвращаемых запросами, то в ваших триггерах аудита необходимо отключить это или изменить существующий код, чтобы учесть их.
  • IMHO триггеры БД обеспечивают повышенную безопасность и упрощенный способ автоматизации аудита, однако они не являются надежными, поскольку любой, имеющий соответствующий доступ, может отключить триггеры, изменить данные и затем снова включить их. Другими словами, убедитесь, что ваши права доступа к БД ограничены.
  • Наличие одной таблицы для истории - неплохой способ, хотя у вас будет больше работы (и данных для хранения), если вы проверяете историю для нескольких таблиц, особенно когда речь идет о восстановлении журнала аудита. Вам также необходимо учитывать проблемы с блокировкой, если существует множество таблиц, пытающихся записать в одну таблицу аудита.
  • Наличие таблицы истории аудита для каждой таблицы - еще один вариант. Вам просто нужно, чтобы каждый столбец в таблице аудита был обнуляемым, а также для сохранения даты и времени действия (вставка / обновление / удаление) и пользователя, связанного с действием.
  • Если вы используете опцию с одной таблицей, если у вас нет много времени для этого, не слишком увлекайтесь попытками проверять только обновления или удаления, хотя может быть соблазнительно избежать вставок (так как большинство приложения делают это чаще, чем обновления или удаления), реконструкция истории аудита требует значительных усилий.
  • Если ваши серверы или данные охватывают несколько часовых поясов, рассмотрите возможность использования соответствующего типа даты и времени, чтобы иметь возможность хранить и восстанавливать временную шкалу, то есть сохранять дату события аудита в UTC, а также включать смещение часового пояса.
  • Эти таблицы аудита могут быть огромными, поэтому имейте стратегию, если они начнут влиять на производительность. Варианты включают разбиение таблицы на разные диски, архивирование и т. Д., В основном, думайте об этом сейчас, а не тогда, когда это становится проблемой:)
5 голосов
/ 03 апреля 2009

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

3 голосов
/ 03 апреля 2009

Я всегда был поклонником использования одной таблицы вместо того, чтобы разбивать ее на «активную» таблицу и таблицу «истории». Я поместил 4 столбца в эти таблицы, все отметки времени: созданы, удалены, начало, конец. «создано» и «удалено» довольно очевидно. Метки времени начала и конца предназначены для случаев, когда запись фактически была «активной» записью. Текущая активная запись будет иметь время «начала» до now() и «конца» NULL. Разделяя «созданное» и «начальное» время, вы можете запланировать изменения, которые произойдут в будущем.

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

Эта идея изначально не моя (хотя я сам заново придумал грубую идею, прежде чем читать о ней) ... подробное обсуждение этой идеи можно найти в этой онлайновой книге .

0 голосов
/ 03 апреля 2009

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

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

Это также похоже на хорошее приложение для AOP (Аспекты), где вы можете использовать отражение в объектной модели для вывода чего-то значимого без большого количества метаданных.

0 голосов
/ 03 апреля 2009

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

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

0 голосов
/ 03 апреля 2009

Участие в сеансе заставляет меня немного насторожиться (вы уверены, что обрабатываете его правильно, когда два пользователя одновременно работают с одними и теми же данными?), Но в целом, да, ведение таблицы истории является правильным вещь.

...