Триггеры базы данных
В прошлом я никогда не был поклонником использования триггеров в таблицах базы данных. Для меня они всегда представляли некоторую "магию", которая должна была произойти на стороне базы данных, далекая от контроля моего кода приложения. Я также хотел ограничить объем работы, которую должен был выполнять БД, поскольку он обычно является общим ресурсом, и я всегда предполагал, что триггеры могут оказаться дорогими в сценариях с высокой нагрузкой.
Тем не менее, я нашел несколько примеров, когда триггеры имели смысл использовать (по крайней мере, по моему мнению, они имели смысл). В последнее время я оказался в ситуации, когда мне иногда может понадобиться "обходить" триггер. Я чувствовал себя виноватым в том, что мне нужно искать способы сделать это, и я все еще думаю, что лучший дизайн базы данных облегчит необходимость этого обхода. К сожалению, эта БД используется несколькими приложениями, некоторые из которых поддерживаются очень неуправляемой командой разработчиков, которые будут кричать о изменениях схемы, поэтому я застрял.
Что вообще говорит о триггерах? Любите? Ненависть em? Думаете, они служат целям в некоторых сценариях?
Подумайте, что необходимость обхода триггера означает, что вы "делаете это неправильно"?
Ответы
Ответ 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, такой как выше, который может изменять данные более чем в одной строке, вы можете включить курсор для обновления всех записей, затронутых триггером. Вы можете увидеть, как это может быть запутано очень быстро.