Является ли это лучшим подходом к созданию контрольного журнала?

StackOverflow https://stackoverflow.com/questions/711597

  •  23-08-2019
  •  | 
  •  

Вопрос

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

04.02.09 21:49 Имя изменено с «Том» на «Крис».

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

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

Это было полезно?

Решение

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

Другие советы

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

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

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

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

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

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top