Триггеры базы данных - PullRequest
       63

Триггеры базы данных

17 голосов
/ 18 августа 2008

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

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

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

Ответы [ 12 ]

12 голосов
/ 18 августа 2008

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

Том Кайт , вице-президент Oracle указал, что он предпочел бы удалить триггеры как функцию базы данных Oracle из-за их частой роли в ошибках. Он знает, что это всего лишь сон, и триггеры здесь, чтобы остаться, но если бы он мог, он удалил бы триггеры из Oracle, он бы (вместе с предложением WHEN OTHERS и автономными транзакциями).

Можно ли использовать триггеры правильно? Совершенно верно.

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

8 голосов
/ 18 августа 2008

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

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

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

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

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

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

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

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

enter image description here

2 голосов
/ 14 октября 2008

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

2 голосов
/ 18 августа 2008

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

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

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

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

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

2 голосов
/ 18 августа 2008

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

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

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

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

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

1 голос
/ 18 августа 2008

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

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

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

0 голосов
/ 18 августа 2008

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

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

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

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

0 голосов
/ 18 августа 2008

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

но на самом деле приходится использовать его экономно, когда,

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

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

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

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

0 голосов
/ 18 августа 2008

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

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

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

0 голосов
/ 18 августа 2008

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...