Intereting Posts

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

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

02/04/09 21:49 Название изменено с "Tom" на "Chris".

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

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

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

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

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

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

  • Если вам нужно сопоставить пользователя, который изменил данные (что вы обычно делаете), то триггеры db должны будут как-то получить эту информацию. Невозможно, но больше работы и нескольких способов приблизиться к этому (db пользователь выполняет запрос, общий столбец пользователя в каждой таблице и т. Д.),
  • Если вы используете триггеры db и полагаетесь на количество поврежденных строк, возвращаемое из запросов, то ваши триггеры аудита должны быть отключены или ваш существующий код изменен для учета их.
  • Триггеры IMHO db предлагают большую безопасность и предлагают более легкий путь автоматизации аудита, однако они не являются надежными, так как любой, у кого есть соответствующий доступ, может отключить триггеры, изменить данные и затем снова включить их. Другими словами, убедитесь, что ваши права доступа к защитой db ограничены.
  • Наличие отдельной таблицы для истории – неплохой путь, хотя у вас будет больше работы (и данных для хранения), если вы проверяете историю для нескольких таблиц, особенно когда речь идет о восстановлении аудита. Вы также должны учитывать проблемы с блокировкой, если есть много таблиц, пытающихся записать в одну таблицу аудита.
  • Еще одна опция – наличие таблицы истории аудита для каждой таблицы. Вам просто нужно, чтобы каждый столбец в таблице аудита был нулевым, а также дата и время действия (вставка / обновление / удаление) и пользователь, связанный с действием.
  • Если вы перейдете с опцией «одна таблица», если у вас не будет много времени для этого, не слишком увлекайтесь попыткой аудита только при обновлении или удалении, хотя может возникнуть соблазн избежать вставки (поскольку большинство приложений делают это чаще, чем обновления или удаления), восстановление истории аудита занимает довольно много работы.
  • Если ваши серверы или данные охватывают несколько часовых поясов, подумайте о том, чтобы использовать соответствующий тип даты и времени, чтобы иметь возможность хранить и восстанавливать временную шкалу, то есть хранить дату события аудита в UTC, а также учитывать смещение часового пояса.
  • Эти таблицы аудита могут стать огромными, поэтому имейте стратегию, если они начнут влиять на производительность. Параметры включают разбиение таблиц на разные диски, архивирование и т. Д. В основном думают об этом сейчас, а не когда это становится проблемой 🙂

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

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

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

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

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

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

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

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

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