в чем разница между триггерами, утверждениями и проверками (в базе данных) - PullRequest
22 голосов
/ 14 марта 2010

Кто-нибудь может объяснить (или предложить сайт или статью) точную разницу между триггерами, утверждениями и проверками, а также описать, где я должен их использовать?

РЕДАКТИРОВАТЬ: я имею в виду в базе данных, а не в других системах или языках программирования.

Ответы [ 5 ]

55 голосов
/ 14 марта 2010

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

CREATE TRIGGER triggerName
AFTER UPDATE
    INSERT INTO CustomerLog (blah, blah, blah)
    SELECT blah, blah, blah FROM deleted

Разница между утверждениями и проверками немного более мутная, многие базы данных даже не поддерживают утверждения.

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

ALTER TABLE accounts 
ADD CONSTRAINT CK_minimumBalance
CHECK (balance >= 100)

Любая попытка вставить значение в столбец с балансом менее 100 приведет к ошибке.

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

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

Пример: все новые клиенты, открывающие счет, должны иметь баланс в размере 100 долларов США; однако после открытия счета их баланс может упасть ниже этой суммы. В этом случае вы должны использовать триггер, потому что вы хотите, чтобы условие оценивалось только при вставке новой записи.

11 голосов
/ 14 марта 2010

В стандарте SQL и ASSERTIONS, и CHECK CONSTRAINTS - это то, что реляционная теория называет «ограничениями»: правилами, которым должны фактически соответствовать данные, содержащиеся в базе данных.

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

TRIGGER - это фрагменты исполняемого кода, для которых СУБД может быть объявлено, что они должны выполняться каждый раз, когда выполняется определенный вид операции обновления (вставка / удаление / обновление) для определенной таблицы. Поскольку триггеры могут вызывать исключения, они являются СРЕДСТВОМ для реализации того же, что и ASSERTION. Тем не менее, с помощью триггеров, все равно программист должен выполнять все кодирование и не делать никаких ошибок.

EDIT

Onedaywhen комментарии re. УТВЕРЖДЕНИЕ / ПРОВЕРКА cnstr. верны. Разница более тонкая (и запутанная). Стандарт действительно допускает подзапросы в ограничениях CHECK. (Большинство продуктов не поддерживают его, поэтому мое «отношение к одной строке» верно для большинства продуктов SQL, но не для стандарта.) Так есть ли разница? Да, все еще есть. Более одного даже.

Первый случай: СТОЛОВЫЕ МУЖЧИНЫ (ID: INTEGER) и ЖЕНСКИЕ СТОЛЫ (ID: INTEGER). Теперь представьте себе правило, согласно которому «никакое значение идентификатора не может появиться как в MEN, так и в таблице WOMEN». Это единственное правило. Намерение ASSERTION состоит в том, чтобы разработчик базы данных сформулировал это единственное правило [и покончил с ним], и СУБД знала, как с этим справиться [эффективно, конечно] и как применять это правило, независимо от того, что конкретно обновление выполняется в базе данных. В этом примере СУБД будет знать, что она должна выполнить проверку для этого правила при ВСТАВКЕ В МУЖЧИН и ВСТАВКЕ В ЖЕНЩИН, но не при УДАЛЕНИИ ИЗ МУЖЧИН / ЖЕНЩИН, или ВСТАВИТЬ В .

Но СУБД недостаточно умны, чтобы делать все это. Итак, что нужно сделать? Разработчик базы данных должен добавить два ограничения CHECK в свою базу данных, одно в таблицу MEN (проверка вновь вставленных идентификаторов MEN по таблице WOMEN) и одно в таблицу WOMAN (проверка наоборот). Вот ваше первое отличие: одно правило, одно ПОЛОЖЕНИЕ, ограничения ДВА ПРОВЕРКА. Ограничения CHECK являются более низким уровнем абстракции, чем ASSERTIONs, потому что они требуют, чтобы разработчик больше задумывался о (a) обо всех видах обновления, которые потенциально могут привести к нарушению его ASSERTION, и (b) какую конкретную проверку следует выполнять для любого из конкретных "видов обновления", которые он нашел в (а). (Хотя мне не очень нравится делать «абсолютные» утверждения о том, что по-прежнему «ЧТО» и что такое «КАК», я бы подытожил, что ограничения CHECK требуют большего «процедурного» мышления (как) разработчиком базы данных, тогда как ASSERTIONs позволить разработчику базы данных сосредоточиться исключительно на "ЧТО" (декларативном).)

Второй случай (хотя я не совсем уверен в этом - так что возьмите с собой немного соли): просто ваше среднее правило RI. Конечно, вы привыкли указывать это с помощью некоторого предложения REFERENCES. Но представьте, что предложение REFERENCES не было доступно. Правило типа «Каждый заказ должен быть размещен известным ЗАКАЗЧИКОМ» на самом деле является правилом, таким образом: единое ПОЛОЖЕНИЕ. Тем не менее, мы все знаем, что такое правило всегда может быть нарушено двумя способами: вставка ORDER (в этом примере) и удаление CUSTOMER. Теперь, в соответствии с предыдущим примером MAN / WOMEN, если бы мы хотели реализовать это единственное правило / ASSERTION с использованием ограничений CHECK, то нам нужно было бы написать ограничение CHECK, которое проверяет существование CUSTOMER при вставках в ORDER, но какое ограничение CHECK могло бы мы пишем, что делает все необходимое при удалении от ЗАКАЗЧИКА? Насколько я могу судить, они просто не предназначены для этой цели. Вот ваше второе отличие: ограничения CHECK связаны исключительно с INSERT, ASSERTIONS могут определять правила, которые также будут проверяться при DELETE.

Третий случай. Представьте себе таблицу COMPOS (componentID: ... процент: INTEGER) и правило о том, что «сумма всех процентов всегда должна быть равна 100». Это единственное правило, и ASSERTION может указать это. Но попробуйте представить, как бы вы применили такое правило с ограничениями CHECK ... Если у вас есть действительная таблица, скажем, с тремя ненулевыми строками, в сумме до сотни, как бы вы применили любое изменение в этой таблице, которое могло бы сохраниться? ваше ограничение CHECK? Вы не можете удалить или обновить (уменьшить) любую строку, не добавляя другие замещающие строки, или обновляя оставшиеся строки, которые суммируют до того же процента. Аналогично для вставки или обновления (увеличения). Вам, по крайней мере, понадобится отложенная проверка ограничений, а затем, что вы собираетесь ПРОВЕРИТЬ? Есть третье отличие: ограничения CHECK предназначены для отдельных строк, в то время как ASSERTIONs также могут определять / выражать правила, которые «охватывают» несколько строк (т. Е. Правила агрегации строк).

6 голосов
/ 08 мая 2014

Утверждения не изменяют данные, они только проверяют определенные условия

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

----------------------------------------------- ---------------------------------

Утверждения не связаны с конкретными таблицами в базе данных и не связаны с конкретными событиями

Триггеры связаны с конкретными таблицами и конкретными событиями

2 голосов
/ 06 февраля 2012

Ограничение базы данных включает условие, которое должно быть выполнено при обновлении базы данных. В SQL, если условие ограничения оценивается как ложное, тогда обновление завершается неудачно, данные остаются неизменными, и СУБД выдает ошибку.

И CHECK, и ASSERTION - это ограничения базы данных, определенные стандартами SQL. Важным отличием является то, что CHECK применяется к конкретной базовой таблице, тогда как ASSERTION применяется ко всей базе данных. Рассмотрим ограничение, которое ограничивает объединенные строки в таблицах T1 и T2 всего 10 строками, например.

CHECK (10 >= (
              SELECT COUNT(*)
                FROM (
                      SELECT *
                        FROM T1
                      UNION
                      SELECT * 
                        FROM T2
                     ) AS Tn
             ))

Предположим, что таблицы пусты. Если это применимо только к ASSERTION и пользователь попытался вставить 11 строк в T1, тогда обновление завершится неудачно. То же самое применимо, если ограничение было применено как ограничение CHECK только к T1. Однако, если ограничение было применено как CHECK ограничение к T2, только ограничение будет выполнено успешно, поскольку оператор, нацеленный на T1, не приводит к проверке ограничений, примененных к T1.

И ASSERTION, и CHECK могут быть отложены (если они объявлены как DEFERRABLE), что позволяет данным временно нарушать условие ограничения, но только внутри транзакции.

Ограничения

ASSERTION и CHECK, включающие подзапросы, являются функциями вне основного стандарта SQL, и ни один из основных продуктов SQL не поддерживает эти функции. MS Access (не совсем продукт промышленного уровня) поддерживает ограничения CHECK, включающие подзапросы, но не отложенные ограничения, а тестирование ограничений всегда выполняется построчно, практические последствия заключаются в том, что функциональность очень ограничена.

Как и ограничения CHECK, к определенной таблице применяется триггер. Следовательно, триггер может использоваться для реализации той же логики, что и ограничение CHECK, но не ASSERTION. Триггер - это процедурный код, и, в отличие от ограничений, пользователь должен нести большую ответственность за такие проблемы, как производительность и обработка ошибок. Большинство коммерческих продуктов SQL поддерживают триггеры (вышеупомянутый MS Access не поддерживает).

0 голосов
/ 18 апреля 2013

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

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