Базы данных триггеры зло? [закрытый]

базы данных триггеры плохая идея?

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

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

единственный раз, когда мы используем триггеры, - это очень простые вещи, такие как установка ModifiedDate.

21 ответов


основные проблемы с триггерами: а) они полностью глобальны - они применяются независимо от контекста активности таблицы; и б) они скрыты; легко забыть, что они есть, пока они не повредят вам с непреднамеренными (и очень таинственными) последствиями.

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


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

мы много используем триггеры, потому что он помещает конкретную деятельность СУБД под контроль базы данных, где она принадлежит. Пользователи СУБД не должны беспокоиться о таких вещах. Целостность данных зависит от сама база данных, не приложения или пользователи, которые его используют. Без ограничений и триггеров и других функций в базе данных приложения могут применять правила, и для уничтожения данных требуется только одно изгоев или багги-приложение/пользователь.

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

кроме того, отсутствие триггеров предотвратит применение правил данных в СУБД, таких как предварительные триггеры, чтобы столбцы имели определенный формат. Обратите внимание, что это отличается от правил целостности данных, которые обычно являются просто внешними ключами.


инструменты никогда не бывают злыми. Применение этих инструментов может быть злом.


триггеры, похоже, хорошо работают для ведения журнала аудита.


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

важность триггеров (на мой взгляд) заключается в этом...
- Любая система всегда должна быть в действительном состоянии
- Код для обеспечения этого действительного состояния должен быть централизован (не написан в каждом SP)

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

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

они звучат резко, и я думаю, что они. Но это основная истина, на мой взгляд...


Я думаю, что триггеры не только не злы, но и необходимы для хорошего дизайна базы данных. Программисты приложений считают, что базы данных зависят только от их приложения. Они часто ошибаются. Если целостность данных должна поддерживаться независимо от того, откуда произошли изменения данных, триггеры являются требованием, и глупо избегать их, потому что некоторые программисты слишком этноцентричны, чтобы учитывать, что что-то другое, чем их ценное приложение, может влиять на вещи. Это не трудно спроектировать или проверьте или устраните неполадки триггера, если вы являетесь компетентным разработчиком баз данных. Также нетрудно определить, что триггер вызывает неожиданный результат, если вам (как и мне) приходит в голову посмотреть туда. Если я получаю ошибку, говоря, что таблица, на которую я не ссылаюсь в своем sp, имеет ошибку FK, я знаю, даже не думая об этом, что триггер вызывает проблему, и поэтому должен любой компетентный разработчик базы данных. Размещение бизнес-правил только в приложении является причиной номер один, которую я нашел плохих данных, поскольку другие понятия не имеют, что правило даже существует и нарушают его в своих процессах. Правила, ориентированные на данные, принадлежат базе данных, и триггеры являются ключевыми для обеспечения более сложных.


в основном, да.

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

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

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


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

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

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


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

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

существует также вопрос "принцип наименьшего удивления", который уже упоминался.


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

теперь они могут быть "злыми", если вы окажетесь в" триггерном аду " с одним триггером, который запускает другие триггеры. Однажды я работал над продуктом COTS, где у них было то, что они называли "триггерами flex"."Эти триггеры были сохранены в таблице, поскольку были скомпилированы динамические SQL stings время, когда они были казнены. Скомпилированные триггеры будут делать посмотрите и посмотрите, есть ли в этой таблице триггеры flex для запуска, а затем скомпилируйте и запустите триггер "flex". В теории это звучало как действительно классная идея, потому что продукт был легко настроен, но на самом деле база данных в значительной степени взорвалась из-за всех компиляций, которые она должна была сделать...

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


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

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


Не зло. Они действительно упрощают такие вещи, как

1.Ведение журнала / аудит изменений записей или даже схем баз данных

У вас может быть триггер на ALTER TABLE, который откатывает изменения в вашей производственной среде. Это должно предотвратить любые случайные изменения таблицы.


2.Обеспечение ссылочной intrgrity (первичный/внешний ключ отношения, и т. д.) по нескольким базам данных


на высоком уровне есть два варианта использования для триггеров1

1), чтобы сделать вещи "автоматически". В этом случае триггеры вызывают побочный эффект, они изменяют данные способами, которые не ожидались, учитывая (примитивный) оператор insert, update или delete, который был выполнен и вызвал срабатывание триггера.

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

2) для обеспечения соблюдения правил целостности данных, кроме тех, с которыми мы можем иметь дело декларативно (используя проверку, первичный ключ, уникальный ключ и внешний ключ). В этом случае все триггеры делают запрос (выбор) данных, чтобы проверить, если изменение, которое делается по INSERT/UPDATE/DELETE разрешено или нет. Точно так же, как для нас декларативные ограничения. Только в этом случае мы (разработчики) запрограммировали органов.

использование триггеров в последнем случае не вредно.

Я веду блог об этом по адресу:http://harmfultriggers.blogspot.com


нет, они не злые - они просто неправильно поняты : - D

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

Если вы разрабатываете БД как часть приложения, логика всегда должна быть в коде или sprocs, выполняющих вызов. Триггеры просто приведут к debug-pain позже.

Если вы понимаете, как блокировка, блокировка и как DBs доступ к файлам на диске, то с помощью триггеров в правильном направлении (для аудит экземпляра или архивирование прямого доступа к БД) может быть действительно ценным.


Они определенно не зло. Я нашел триггеры, драгоценные при рефакторинге схем базы данных, при переименовании столбца или разделении столбца на два столбца или наоборот (пример: имя/фамилия) и содействии переходу.

Они также очень полезны для аудита.


этот ответ относится конкретно к SQL Server. (хотя это может также применяться к другим RDBMSs, я понятия не имею. Я бы предпочел дать его в качестве ответа здесь но это было закрыто как обман этого.)

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

пример, приведенный в BOL под "Управление Безопасностью Триггера" заголовок пользователя, который создает триггер, содержащий код GRANT CONTROL SERVER TO JohnDoe ; для того, чтобы расширять свои полномочия.


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


Я думаю, что они могут быть злыми, но только такими же злыми, как и все остальное в развитии.

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

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

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


сказать, что они злые, - это преувеличение, но они могут вызвать меш. Когда срабатывание одного триггера вызывает срабатывание других триггеров, это становится очень сложным. Допустим, они неприятны:http://www.oracle.com/technology/oramag/oracle/08-sep/o58asktom.html

выполнение бизнес-логики в Oracle с триггерами сложнее, чем кажется из-за проблем с несколькими параллелизмом. Вы не видите изменений в другом сеансе, пока не зафиксированы другие сеансы.


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

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


идея триггеров-это не зло, ограничение вложенности триггеров-это зло.