Когда я первоначально изучал SQL, мне всегда говорили, что использовать триггеры можно только в том случае, если вам это действительно нужно, и по возможности использовать хранимые процедуры, если это возможно.
К сожалению, в то время (добрых несколько лет назад) я не был настолько любопытен и не заботился об основах, как сейчас, поэтому никогда не спрашивал, почему.
Каково мнение сообщества в этом? Является ли это чьим-то личным предпочтением или следует избегать триггеров (точно так же, как курсоров), если для этого нет веских причин.
Ответы:
В статье Википедии о триггерах базы данных представлен хороший обзор того, что такое триггеры и когда их использовать в разных базах данных.
Следующее обсуждение основано только на SQL Server.
Использование триггеров вполне допустимо, когда их использование оправдано. Например, они имеют хорошую ценность для аудита (хранения истории данных), не требуя явного процедурного кода с каждой командой CRUD в каждой таблице.
Триггеры дают вам контроль непосредственно перед изменением данных и сразу после их изменения. Это позволяет:
Возможно, некоторые из причин этого:
Некоторые различия между триггерами и хранимыми процедурами без триггера (среди прочих):
источник
Триггеры являются требованием для любых сложных правил целостности данных. Они не могут быть применены нигде, кроме базы данных, иначе у вас будут проблемы с целостностью данных.
Они также являются лучшим местом для аудита, если вы не хотите регистрировать все изменения в базе данных (что является проблемой аудита из приложения).
Триггеры могут вызывать проблемы с производительностью, если они не написаны тщательно, а разработчики недостаточно осведомлены, чтобы хорошо их написать. Это часть того, где они получают свой плохой рэп.
Триггеры часто медленнее других средств поддержания целостности данных, поэтому, если вы можете использовать проверочное ограничение, используйте его вместо триггера.
Легко написать плохие триггеры, которые делают глупые вещи, такие как попытка отправить электронную почту. Вы действительно хотите быть не в состоянии изменить записи в БД, если почтовый сервер выходит из строя?
В SQL-сервере триггеры работают с партией записей. Слишком часто разработчики думают, что им нужно обрабатывать только одну вставку, обновление или удаление одной записи. Это не единственный вид изменений данных, которые происходят с базой данных, и все триггеры следует тестировать в условиях изменения 1 записи и множества изменений записи. Если вы забудете выполнить второй тест, это может привести к крайне плохо выполненным триггерам или потере целостности данных.
источник
Использование триггеров базы данных
источник
Другой случай использования, с которым я лично сталкивался, касается баз данных, к которым обращается более чем одна программа. Если вы хотите реализовать функциональность, но не перепроектировать все системы для нее, триггер делает разумное решение.
Например, я недавно работал над базой данных, которая ранее существовала исключительно как офисная система. Когда веб-приложение было написано для взаимодействия с ним, мы хотели внедрить систему уведомлений (например, подобную stackexchange), которая запускалась бы несколькими событиями, такими как обработка транзакции и т. Д. Мы смогли реализовать триггер, чтобы обновления в служебной части офиса запускали триггер, чтобы создать уведомление для веб-интерфейса и сообщить пользователю, что его транзакция была обработана офисом.
источник
Триггеры могут использоваться для наложения ограничений на базу данных, которые не могут быть применены во время создания схемы базы данных и любых операторов DML.
источник
Допустим, вам нужно передавать данные в стороннюю систему практически в реальном времени. Ваша таблица содержит 950 гигабайт данных, поэтому она слишком велика, чтобы просто отправить всю таблицу в стороннее приложение.
Вместо этого вы накапливаете изменения в очереди. Некоторая внешняя программа будет затем периодически выталкивать небольшие партии данных в очереди.
В системе более 2000 хранимых процедур. Вы также знаете, что тонны sql существуют в исходном коде. Чтобы гарантировать правильное заполнение очереди, вам нужно будет просмотреть все сохраненные процедуры и код и надеяться, что вы ничего не пропустите.
Вместо этого вы можете поместить триггер в таблицу, чтобы обновлять очередь. Гарантированно не пропустить ничего. Одно центральное расположение. Производительность снижается? Не совсем, потому что нельзя избежать попадания в очередь, будь то по триггеру или по внешнему.
В этом сценарии я бы сказал, что использование триггера - плохой выбор дизайна. Если позже вы захотите использовать новый метод отправки данных (скажем, очередь не работает), и интерфейс изменится, если вы используете триггер. Триггеры часто являются лучшим выбором. Не слушайте догматических анти-спусковых фанатов.
источник
Триггер, который отправляет электронную почту, не обязательно является «глупой» идеей. Что глупо, так это не предвидеть перебои с электронной почтой в дизайне и обрабатывать их без потери данных. «Глупая» часть этого действительно плоха для несуществующей обработки ошибок ленивыми разработчиками, которые чувствуют, что они невосприимчивы к ошибкам.
Я также хотел бы предложить наблюдение, что триггер может быть простым путем вызова хранимой процедуры / функции, которая может быть произвольно сложной и может быть многократно использована многократными триггерами или другими хранимыми процедурами. Вот почему есть пакеты и библиотеки.
Фанатизм действительно наносит вред.
источник