Подтвердить что ты не робот

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

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

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

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

4b9b3361

Ответ 1

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

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

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

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

Ответ 2

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

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

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

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

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

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

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

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

enter image description here

Ответ 3

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

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

Некоторые причины, по которым мне не нравятся триггеры:

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

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

Ответ 4

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

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

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

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

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

Ответ 5

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

Ответ 6

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

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

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

Ответ 7

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

Ответ 8

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

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

Ответ 9

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

Ответ 10

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

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

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

Ответ 11

Общий вентилятор,

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

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

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

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

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

Ответ 12

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

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

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

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