Сведения о вопросе

rjevskii

03:36, 23rd August, 2020

Теги

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

Просмотров: 583   Ответов: 12

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

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

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



  Сведения об ответе

lesha

19:05, 4th August, 2020

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

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

Можно ли правильно использовать триггеры? Абсолютно.

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


  Сведения об ответе

dumai

14:05, 4th August, 2020

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

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

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

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

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

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

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

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

enter image description here


  Сведения об ответе

SKY

14:29, 13th August, 2020

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

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

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

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

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


  Сведения об ответе

padenie

22:59, 22nd August, 2020

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

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

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

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

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


  Сведения об ответе

prince

01:10, 23rd August, 2020

"Никогда не создавайте триггер для проверки ограничений целостности, которые пересекают строки в таблице" - я не могу согласиться. Вопрос заключается в том, что предложения 'SQL Server' и CHECK ограничений в SQL сервере не могут содержать подзапрос; хуже того, реализация, по-видимому, имеет 'hard coded' предположение, что CHECK будет включать только одну строку, поэтому использование функции не является надежным. Итак, если мне нужно ограничение, которое законно включает более одной строки - и хорошим примером здесь является секвенированный первичный ключ в классической временной таблице 'valid time', где мне нужно предотвратить перекрывающиеся периоды для одной и той же сущности-как я могу сделать это без триггера? Помните, что это первичный ключ, который гарантирует целостность данных, поэтому о его применении в любом другом месте, кроме DBMS, не может быть и речи. Пока ограничения CHECK не получат подзапросы, я не вижу альтернативы использованию триггеров для определенных видов ограничений целостности.


  Сведения об ответе

PHPH

05:35, 27th August, 2020

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

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

В общем, я бы проголосовал за "they serve a purpose in some scenarios". Я всегда нервничаю из-за последствий для производительности.


  Сведения об ответе

piter

12:05, 7th August, 2020

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

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

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

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


  Сведения об ответе

darknet

20:23, 10th August, 2020

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


  Сведения об ответе

SILA

11:52, 8th August, 2020

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

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


  Сведения об ответе

lourence

02:45, 4th August, 2020

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


  Сведения об ответе

FAriza

09:09, 21st August, 2020

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

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

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


  Сведения об ответе

$DOLLAR

12:00, 13th August, 2020

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

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

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

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

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

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


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться