Плюсы и минусы триггеров против хранимых процедур денормализации
Когда речь заходит о денормализации данных в транзакционной базе данных для повышения производительности, существует (по крайней мере) три различных подхода:
-
Протолкнуть обновления через хранимые процедуры, которые обновляют как нормализованные транзакционные данные, так и денормализованные отчетные / аналитические данные;
-
Реализуйте триггеры на транзакционных таблицах, которые обновляют вторичные таблицы; это почти всегда маршрут, используемый при сохранении историй;
-
Отложите обработка в ночной пакетный процесс, возможно, выполнение ETL в витрине данных / хранилище.
Предположим для целей этого вопроса, что Вариант №3 не является жизнеспособным, потому что домен требует, чтобы денормализованные данные были согласованы с нормализованными данными во все времена. Иерархические агрегаты, с которыми я имею дело довольно часто, являются одним из примеров этого.
Я использовал оба первых подхода изрядно, и в последнее время я склоняюсь к следующему. триггерный подход, но мне интересно, есть ли какие-то" готы", которые я еще не обнаружил, и я подумал, что стоит задать этот вопрос, чтобы у меня были некоторые идеи, которые я буду иметь в виду при принятии долгосрочных решений в будущем.
Итак, по вашему опыту, каковы плюсы и минусы любого инструмента для конкретной цели поддержания денормализованных данных в реальном времени? В каких ситуациях вы предпочли бы одно другому и почему?(P.S. Пожалуйста, никаких ответов типа " триггеры слишком сложны "или" все обновления должны всегда проходить через сохраненный proc " - сделайте его соответствующим контексту вопроса.)
3 ответа:
Триггеры
Полезны, когда вы используете несколько путей обновления в таблице.
Мы используем хранимые procs и имеем по крайней мере около 4 путей (добавить, обновить, деактивировать, скопировать)
Легче работать с данными, которые мы только что вставили/обновили в триггер, независимо от того, какое действие мы выполняем или сколько строк мы затрагиваем.
Сохраненный proc работает для одного пути обновления только я чувствую: если вы не хотите повторить код...
Теперь TRY / CATCH в триггерах означает корректную, предсказуемую обработку ошибок: триггеры на SQL Server 2000 и более ранних версиях вызывали прерывание пакета при ошибке / откате, что не идеально (мягко говоря!). Так что триггеры теперь все равно надежнее.
Триггеры являются автоматическими побочными эффектами и почти наверняка укусят вас, когда вы хотите что-то сделать, но не можете из-за побочных эффектов триггеров. в основном такие вещи, как участие вашей системы в некоторых транзакциях XA с другими внешними системами. Триггеры делают это невозможным. Кроме того, это логика побочных эффектов, которая может быть активирована только повторным запуском активатора триггера. Если вы хотите воссоздать данные в хранилище, вы не можете просто запустить какую-то процедуру и воссоздав его, вы должны выполнить все действия, которые будут запускать триггеры, это кошмар. Вставки, обновления и удаления должны быть идемпотентными и ортогональными. Триггеры без необходимости усложняют рабочие процессы, даже если вы думаете, что они упрощают их, это не так.
Это зависит от ваших бизнес-требований и того, как используется ваша база данных. Например, предположим, что существует много приложений и много импорта, которые влияют на таблицу (у нас есть сотни вещей, которые могут повлиять на наши таблицы) . Предположим также, что иногда возникает необходимость писать запросы, которые запускаются из SSMS (да даже на prod), чтобы сделать такие вещи, как обновление всех цен на 10%. Если вы делаете такие вещи, то сохраненный proc непрактичен, у вас никогда не будет всех возможных способов повлиять на база данных закрыта.
Если это изменение данных необходимо для целостности данных или многих приложений или процессов (импорт, задания SQL Server и т. д.) может влиять на данные, тогда он принадлежит триггеру.
Если изменение данных требуется только иногда или у вас есть полный контроль над тем, как изменяются данные только из одного приложения, то сохраненный proc подойдет.