Плюсы и минусы триггеров против хранимых процедур денормализации

когда дело доходит до денормализации данных в транзакционной базе данных для производительности, существует (по крайней мере) три разных подхода:

  1. нажмите обновления через хранимые процедуры, которые обновляют как нормализованные транзакционные данные, так и денормализованные данные отчетности/анализа;

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

  3. отложите обработку до ночного пакетного процесса, возможно, выполняя ETL в Data mart / warehouse.

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

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

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

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

3 ответов


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

мы используем сохраненные процессы и имеем около 4 путей по крайней мере (добавить, обновить, деактивировать, скопировать)

легче работать с данными, которые мы только что вставили / обновили в триггер, независимо от того, какое действие мы делаем или сколько строк мы затрагиваем.

сохраненный proc работает только для одного пути обновления, я чувствую: если вы не хотите повторить код...

теперь, TRY / CATCH в триггерах означает правильно, предсказуемая обработка ошибок: триггеры на SQL Server 2000 и более ранних версиях вызывают прерывание пакета при ошибке/откате, что не идеально (мягко говоря!). Так что теперь триггеры надежнее.


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


Это зависит от ваших бизнес-требований и как используется база данных. Например, предположим, что есть много приложений и много импорта, которые влияют на таблицу (у нас есть сотни вещей, которые могут повлиять на наши таблицы) . Предположим также, что иногда необходимо писать запросы, которые запускаются из SSMS (да даже на prod), чтобы сделать такие вещи, как обновление всех цен на 10%. Если вы делаете эти типы вещей, то сохраненный proc непрактичен, у вас никогда не будет всех возможных способов повлиять на база данных охвачена.

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

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