Вопросы производительности для триггеров и ограничений - PullRequest
17 голосов
/ 29 сентября 2008

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

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

Ответы [ 12 ]

15 голосов
/ 29 сентября 2008

Ограничения руки вниз!

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

  • С помощью триггеров вы указываете, как обрабатывать данные (во вставках, обновлениях и т. Д.). Это «нереляционный» способ ведения дел.

Чтобы лучше объяснить себя с помощью аналогии: правильный способ написания SQL-запроса - указать «что вы хотите», а не «как его получить» & ndash; позвольте РСУБД выяснить лучший способ сделать это для вас. То же самое применимо и здесь: если вы используете триггеры, вы должны помнить о различных вещах, таких как порядок выполнения, каскадирование и т. Д. Пусть SQL сделает это для вас с ограничениями, если это возможно.

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

13 голосов
/ 29 сентября 2008

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

Триггеры не так плохи, как дискредитация (если их использовать правильно), хотя я всегда буду использовать ограничение там, где это возможно. В современной RDMS накладные расходы на производительность триггеров сопоставимы с ограничениями (конечно, это не означает, что кто-то не может поместить ужасный код в триггер!).

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

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

7 голосов
/ 13 ноября 2008

В дополнение к другим причинам использования ограничений оптимизатор Oracle может использовать ограничения в своих интересах.

Например, если у вас есть ограничение, говорящее (Amount >= 0), и вы выполняете запрос с помощью WHERE (Amount = -5) Oracle сразу узнает, что соответствующих строк нет.

7 голосов
/ 29 сентября 2008

Триггеры могут перерасти в проблему производительности. Примерно в то же время, что происходит, они также стали кошмаром обслуживания. Вы не можете понять, что происходит и (бонус!), Приложение ведет себя беспорядочно с «ложными» проблемами с данными. [На самом деле, они вызывают проблемы.]

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

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

«Как получить абсолютную уверенность в том, что все правильно используют модель данных?»

Две (с половиной) техники.

  1. Убедитесь, что модель вправо : соответствует реальной проблемной области. Никаких хаков, обходных путей или ярлыков, которые могут быть отсортированы только с помощью сложных объяснений, хранимых процедур и триггеров.

  2. Помогите определить уровень бизнес-модели приложений. Уровень кода приложения, который все разделяют и используют повторно.

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

Триггеры - это крушение поезда, которое должно произойти. Ограничения нет.

5 голосов
/ 29 сентября 2008

Ограничения и триггеры для двух разных вещей. Ограничения используются для ограничения домена (допустимых входных данных) ваших данных. Например, SSN будет храниться как char (9), но с ограничением [0-9] [0-9] [0-9] [0-9] [0-9] [0-9] [ 0-9] [0-9] [0-9] (все числовые).

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

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

4 голосов
/ 29 сентября 2008

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

3 голосов
/ 02 октября 2008

@ onedaywhen

Вы можете иметь запрос в качестве ограничения в SQL Server, вам просто нужно уметь вписать его в скалярную функцию: http://www.eggheadcafe.com/software/aspnet/30056435/check-contraints-and-tsql.aspx

2 голосов
/ 29 сентября 2008

@ Марк Брэкетт: «Ограничения используются для ограничения домена ... Триггеры - это способ реализации бизнес-логики»: в SQL Server не все так просто, поскольку функциональность его ограничений ограничена, например, еще не полный SQL-92. Возьмите классический пример последовательного «первичного ключа» во временной таблице базы данных: в идеале я бы использовал ограничение CHECK с подзапросом, чтобы предотвратить перекрывающиеся периоды для одной и той же сущности, но SQL Server не может этого сделать, поэтому мне нужно использовать спусковой крючок. В SQL Server также отсутствует возможность SQL-92 откладывать проверку ограничений, но вместо этого они (по сути) проверяются после каждого оператора SQL, поэтому, опять же, может потребоваться триггер, чтобы обойти ограничения SQL Server.

2 голосов
/ 29 сентября 2008

Если вообще возможно использовать ограничения. Они имеют тенденцию быть немного быстрее. Триггеры должны использоваться для сложной логики, которую ограничение не может обработать. Запись триггера также сложна, и если вы обнаружите, что должны написать триггер, убедитесь, что вы используете операторы на основе набора, поскольку триггеры работают со всей вставкой, обновлением или удалением (Да, будут случаи, когда затрагивается более одной записи, планируйте на этом!), не только одна запись за один раз. Не используйте курсор в триггере, если его можно избежать.

Насколько поставить логику в приложении вместо триггера или ограничения. НЕ ДЕЛАЙ ЭТОГО!!! Да, приложения должны иметь проверки перед отправкой данных, но целостность данных и бизнес-логика должны быть на уровне базы данных, иначе ваши данные будут испорчены, когда к нему подключатся несколько приложений, когда глобальные вставки будут выполняться вне приложения и т. Д. Данные Целостность является ключом к базам данных и должна обеспечиваться на уровне базы данных.

1 голос
/ 09 января 2014

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

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

У многих людей есть много способов сделать это. Но одна вещь наверняка, вам придется выполнять вставку для каждого обновления / вставки / удаления в этой таблице

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

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