Плюсы, минусы и подводные камни таблиц истории - с использованием триггеров, sproc или на уровне приложения [закрыто]

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

Вопрос

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

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

  • Запускает в главной таблице функции обновления, вставки и удаления.(База данных)
  • Хранимые процедуры.(База данных)
  • Прикладной уровень.(Приложение)

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

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

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

Решение

Я бы выразился так:

  • Сохраненные процедуры: они будут обойдены, если вы измените таблицу напрямую.Безопасность в базе данных может контролировать это
  • Применение: та же сделка.Кроме того, если у вас есть несколько приложений, возможно, на разных языках, это должно быть реализовано в каждом стеке, что несколько избыточно;и
  • Триггеры: прозрачен для приложения и будет фиксировать все изменения.Это мой предпочтительный метод.

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

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

Тем, кто считает, что триггеры безопаснее sprocs, потому что их нельзя обойти, я напоминаю им, что они делают следующее предположение:

!) Существуют разрешения, которые не позволяют пользователям выполнять ТРИГГЕР ОТКЛЮЧЕНИЯ [но тогда также могут существовать разрешения для ограничения всего доступа к базе данных, за исключением ВЫПОЛНЕНИЯ в sprocs, что является обычным шаблоном для корпоративных приложений] - поэтому необходимо предполагать правильные разрешения, и, следовательно, sprocs равны триггерам с точки зрения безопасности и возможности обхода

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

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

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

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

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

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

  1. Триггеры в часто используемом (скажем, многопользовательском приложении на основе SaaS) могут быть чрезвычайно дорогими

  2. В некоторых сценариях несколько полей могут стать избыточными.Триггеры хороши только тогда, когда вам абсолютно ясно, какие поля нужно регистрировать;хотя при использовании приложения у вас мог бы быть уровень перехватчика, который мог бы помочь вам регистрировать определенные поля на основе "конфигурации";хотя и со своей долей накладных расходов

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

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

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

Изменить Сбор данных: Это функция доступна в SQL Server 2008 R2 +, но только в enterprise edition.Это позволяет вам выбирать таблицы, которые вы хотите отслеживать, и SQL Server выполнит эту работу за вас.Он работает путем чтения журнала транзакций и заполнения таблиц истории данными.

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

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

Триггеры: Отлично работает для небольшого количества таблиц, где не слишком много триггеров для управления.Если у вас есть много таблиц, которые вы хотите провести аудит, то вам следует рассмотреть какой-нибудь сторонний инструмент для этого.

Все это работает на уровне базы данных и полностью прозрачно для приложения.

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

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

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

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