2008-08-18 3 views
17

В прошлом я никогда не был поклонником использования триггеров в таблицах базы данных. Для меня они всегда представляли некоторую «магию», которая должна была произойти на стороне базы данных, далекая от контроля моего кода приложения. Я также хотел ограничить объем работы, которую должен был выполнять БД, поскольку он обычно является общим ресурсом, и я всегда предполагал, что триггеры могут стать дорогими в сценариях с высокой нагрузкой.Базовые триггеры

Тем не менее, я нашел несколько примеров, когда триггеры имели смысл использовать (по крайней мере, по моему мнению, они имели смысл). В последнее время я оказался в ситуации, когда мне иногда может понадобиться «обходить» триггер. Я чувствовал себя виноватым в том, что мне нужно искать способы сделать это, и я все еще думаю, что лучший дизайн базы данных облегчит необходимость этого обхода. К сожалению, эта БД используется несколькими приложениями, некоторые из которых поддерживаются очень неуправляемой командой разработчиков, которая будет кричать о изменениях схемы, поэтому я застрял.

Что общего в этом вопросе о триггерах? Любите? Ненависть em? Думаете, они служат целям в некоторых сценариях? Думаете, что необходимость обхода триггера означает, что вы «делаете это неправильно»?

ответ

12

Триггеры обычно используются неправильно, вводят ошибки, и поэтому их следует избегать. Никогда не создавайте триггер для проверки целостности, который пересекает строки в таблице (например, «средняя зарплата по отделам не может превышать X»).

Tom Kyte, вице-президент Oracle указал, что он предпочел бы получить базу данных remove triggers as a feature of the Oracle из-за их частых роль в багах. он знает, что это всего лишь сон, и спусковые здесь остаться, но если бы он мог, он бы удалить спусковые от Oracle, он бы (вместе с КОГДА дизъюнкция ОСТАЛЬНЫХ и автономные сделки).

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

2

Я работаю с веб-приложениями и winforms в C# и I HATE триггеры со страстью. Я никогда не сталкивался с ситуацией, когда я мог бы оправдать использование триггера для перемещения этой логики в бизнес-уровень приложения и репликацию логики запуска там.

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

Некоторые причины, почему я не люблю спусковые:

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

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

+0

Я использую триггеры для условий вставки/обновления/удаления для увеличения/уменьшения счетчиков на таблице. Сейчас это единственный раз, когда я его использую. Эти триггеры в порядке? – 2010-10-20 12:48:49

0

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

1

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

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

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

2

Триггеры могут быть очень полезными. Они также могут быть очень опасными. Я думаю, что они подходят для задач уборки дома, таких как заполнение данных аудита (созданных, измененная дата и т. Д.), А в некоторых базах данных можно использовать для ссылочной целостности.

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

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

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

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

+0

+1 для неинвазивно заполняемых данных аудита. – zacharydl 2013-11-08 04:49:09

0

Я впервые использовал триггеры пару недель назад. Мы изменили производственный сервер с SQL 2000 на SQL 2005 и обнаружили, что драйверы ведут себя по-разному с полями NText (хранящими большой XML-документ), отбрасывая последний байт. Я использовал триггер в качестве временного исправления для добавления дополнительного фиктивного байта (пробела) в конец данных, решая нашу проблему, пока не будет развернуто правильное решение.

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

8

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

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

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

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

Что касается сокращения объема работы: базы данных потрясающе эффективны, когда им не приходится иметь дело с внешним миром; вы действительно удивитесь, насколько даже переключение процесса ухудшает производительность. Это еще один недостаток хранимых процедур: вместо дюжины звонков в базу данных (и все связанные с ними круговые поездки) есть один.

Сбивка предметов в одной хранимой процедуре в порядке, но что происходит, когда что-то идет не так? Скажем, у вас есть 5 шагов, и первый шаг не удается, что происходит с другими шагами? Вам нужно добавить целую кучу логики, чтобы удовлетворить эту ситуацию. Как только вы начнете делать это, вы потеряете преимущества хранимой процедуры в этом сценарии.

Бизнес-логика должна идти куда-то, и есть много подразумеваемых правила домена, внедренные в проектировании базы данных - отношения, ограничение и так далее попытка систематизировать бизнес-правила, говоря, например, пользователь может быть только один пароль. Учитывая, что вы начали перетаскивать бизнес-правила на сервер базы данных, имея эти отношения и т. Д., Где вы рисуете линию? Когда база данных отказывается от ответственности за целостность данных и начинает доверять вызывающим приложениям и пользователям базы данных, чтобы понять это правильно? Хранимые процедуры с этими встроенными в них правилами могут подтолкнуть большую политическую власть в руки администраторов баз данных. Это сводится к тому, сколько уровней будет существовать в вашей n-уровневой архитектуре; если есть презентация, бизнес и уровень данных, где лежит разделение между бизнесом и данными? Что добавляет значение бизнес-уровня? Будете ли вы запускать бизнес-уровень на сервере базы данных в качестве хранимых процедур?

Да, я думаю, что необходимость обхода триггера означает, что вы «делаете это неправильно»; в этом случае триггер не для вас.

enter image description here

0

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

0

Что касается сокращения объема работы: базы данных потрясающе эффективны, когда им не нужно иметь дело с внешним миром; вы действительно удивитесь, насколько даже переключение процесса ухудшает производительность. Это еще один недостаток хранимых процедур: вместо дюжины звонков в базу данных (и все связанные с ними круговые поездки) есть один.

Это немного не по теме, но вы также должны знать, что вы смотрите только на это из одного потенциального положительного.

Сборка предметов в одной хранимой процедуре в порядке, но что происходит, когда что-то идет не так? Скажем, у вас есть 5 шагов, и первый шаг не удается, что происходит с другими шагами? Вам нужно добавить целую кучу логики, чтобы удовлетворить эту ситуацию. Как только вы начнете делать это, вы потеряете преимущества хранимой процедуры в этом сценарии.

0

Всего вентилятор,

, но на самом деле должны использовать его экономно, когда

  • Необходимость поддерживать согласованность (особенно если таблицы измерений используются на складе, и мы должны связать данные в таблицу фактов с их надлежащим размером. Иногда подходящая строка в таблице размеров может быть очень дорогой для вычисления, поэтому вы хотите, чтобы ключ был написан прямо в таблице фактов, один из хороших способов поддерживать, что «отношение» имеет триггер.

  • нужно войти изменения (в таблице аудита, например, полезно знать, что @@ пользователь сделал изменения и когда это произошло)

Некоторые СУБД, как SQL Server 2005 также предоставит вам триггеры CREATE/ALTER/DROP (так что вы можете узнать, кто создал какую таблицу, когда, опустил какой столбец, когда и т. Д.)

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

0

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

Кроме того, в MS SQL Server триггеры запускаются один раз за команду sql, а не за строку. Например, следующая инструкция sql будет запускать триггер только один раз.

UPDATE tblUsers 
SET Age = 11 
WHERE State = 'NY' 

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

+4

Пожалуйста, не используйте курсор в триггере. Да, вам нужно учитывать несколько вставк строк, обновлений или удалений, но вам нужно сделать это с помощью набора. Я удалил курсор из триггера, где я работал, и вставка из 40 000 записей изменилась с 45 минут до 30 секунд. – HLGEM 2008-11-11 18:16:26

2

«Никогда не создавайте триггер для проверки целостности целостности, которая пересекает строки в таблице» - я не могу согласиться. В вопросе помечены «SQL Server», а условия ограничений CHECK в SQL Server не могут содержать подзапрос; хуже, реализация, похоже, имеет «жестко закодированное» предположение, что CHECK будет включать только одну строку, поэтому использование функции не является надежным. Поэтому, если мне нужно ограничение, которое законно включает более одной строки, и хорошим примером здесь является секвенсорный первичный ключ в классической временной таблице «допустимого времени», где мне нужно предотвратить периоды перекрытия для одного и того же объекта - как можно Я делаю это без триггера? Помните, что это первичный ключ, что-то, чтобы обеспечить целостность данных, поэтому принудительное использование его в любом месте, кроме СУБД, не может быть и речи. Пока ограничения CHECK не получат подзапросы, я не вижу альтернативы использованию триггеров для определенных ограничений целостности.

 Смежные вопросы

  • Нет связанных вопросов^_^