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

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

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

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

  • Отложите обработку на ночной пакетный процесс, возможно, сделав ETL в хранилище данных/хранилище.

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

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

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

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

Ответ 1

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

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

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

Сохраненная процедура работает только для одного пути обновления: если вы не хотите повторять код...

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

Ответ 2

Триггеры - это автоматические побочные эффекты и почти наверняка укусят вас по линии, когда вы хотите что-то сделать, и не можете из-за побочных эффектов триггеров. В основном такие вещи, как участие вашей системы в некоторых транзакциях XA с другими внешними системами. Триггеры делают это НЕВОЗМОЖНО. Также это логика Side Effect, которая может ТОЛЬКО активироваться, снова активируя активатор триггера. Если вы хотите воссоздать данные в Складе, вы не можете просто запустить некоторую процедуру и воссоздать ее, вы должны выполнить все действия, которые будут запускать триггеры, это кошмар. ВСТАВКИ, ОБНОВЛЕНИЯ и УДАЛЕНИЯ должны быть идемпотентными и ортогональными. Триггеры бесполезно усложняют рабочие процессы, даже если вы думаете, что они упрощают их, это не так.

Ответ 3

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

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

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