Открыть сервис

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

Триггер базы данных — это особая процедура (набор инструкций), которая хранится в системе управления базами данных (СУБД) и автоматически выполняется при наступлении определённого события, связанного с таблицей или представлением (view). Основное назначение триггера — обеспечение целостности данных, автоматизация бизнес-логики, аудит изменений и поддержка сложных ограничений, которые невозможно реализовать стандартными средствами (например, с помощью ограничений CHECK или внешних ключей).

История

Концепция триггеров возникла в ранних реляционных СУБД в 1980-х годах. Одной из первых коммерческих систем, реализовавших триггеры, стала Ingres (1981). В 1986 году стандарт SQL-86 не включал триггеры, однако уже в SQL:1999 (ISO/IEC 9075) они были впервые стандартизированы. В 2003 году стандарт SQL:2003 уточнил синтаксис и семантику, включая поддержку триггеров INSTEAD OF для представлений.

В 1990-е годы триггеры стали неотъемлемой частью таких СУБД, как Oracle (с версии 7), Microsoft SQL Server (с версии 6.5), PostgreSQL (с версии 7.1) и MySQL (с версии 5.0). В России триггеры активно используются в системах на базе СУБД «Линтер» (АО «Линтер») и «Postgres Professional» (АО «Постгрес Профессиональный»), а также в зарубежных решениях, развёрнутых в российских организациях.

Классификация

Триггеры классифицируются по нескольким признакам.

По времени выполнения относительно события

  • BEFORE (ДО) — выполняются до того, как операция (INSERT, UPDATE, DELETE) будет применена к строке. Используются для проверки данных, модификации вставляемых значений или предотвращения недопустимых операций.
  • AFTER (ПОСЛЕ) — выполняются после того, как операция завершена. Используются для каскадных изменений, аудита, обновления агрегатных данных.
  • INSTEAD OF (ВМЕСТО) — выполняются вместо операции. Применяются в основном для представлений (views), позволяя выполнять DML-операции над представлениями, которые в противном случае были бы необновляемыми.

По уровню срабатывания

  • Row-level (построчные) — срабатывают один раз для каждой строки, затронутой операцией. Например, при UPDATE, затрагивающем 100 строк, триггер выполнится 100 раз.
  • Statement-level (операторные) — срабатывают один раз на всю операцию, независимо от количества затронутых строк. Используются для выполнения действий, не зависящих от конкретных строк (например, отправка уведомления).

По типу события

  • INSERT — при вставке новой строки.
  • UPDATE — при обновлении существующей строки.
  • DELETE — при удалении строки.
  • TRUNCATE — в некоторых СУБД (например, PostgreSQL) поддерживается отдельный триггер на операцию TRUNCATE.

По области действия

  • Табличные — привязаны к конкретной таблице.
  • Представленческие — привязаны к представлению (view).
  • Системные — в некоторых СУБД (например, Oracle) существуют триггеры на события уровня базы данных (LOGON, LOGOFF, DDL-операции).

Устройство и синтаксис

Триггер состоит из следующих компонентов:

  1. Имя триггерауникальный идентификатор в схеме.
  2. Событие — INSERT, UPDATE, DELETE (или их комбинация).
  3. Время выполнения — BEFORE, AFTER, INSTEAD OF.
  4. Уровень — FOR EACH ROW (построчный) или FOR EACH STATEMENT (операторный).
  5. Тело триггера — набор инструкций на процедурном языке СУБД (PL/SQL в Oracle, T-SQL в MS SQL Server, PL/pgSQL в PostgreSQL, SQL/PSM в MySQL и т.д.).

Пример синтаксиса на PostgreSQL:

``sql CREATE TRIGGER check_salary_before_insert BEFORE INSERT ON employees FOR EACH ROW EXECUTE FUNCTION validate_salary(); ``

В теле триггера обычно используются специальные переменные (например, NEW — новая строка при INSERT/UPDATE, OLD — старая строка при UPDATE/DELETE), которые позволяют обращаться к значениям полей.

Применение

Обеспечение целостности данных

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

Аудит изменений

Триггеры, срабатывающие на UPDATE и DELETE, могут записывать старые значения в отдельную таблицу аудита, фиксируя кто, когда и что изменил. Это широко используется в российских банковских и государственных информационных системах (например, в АС «Управление» и «1С:Предприятие»).

Автоматическое обновление производных данных

Например, при вставке новой строки в таблицу orders триггер может автоматически обновить поле total_amount в таблице customers, суммируя стоимость всех заказов клиента.

Каскадные операции

Триггеры могут выполнять каскадные удаления или обновления, которые не поддерживаются внешними ключами (например, мягкое удаление с установкой флага deleted).

Бизнес-логика

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

Примеры

Пример 1: Аудит изменений (PostgreSQL)

```sql CREATE TABLE employees ( id SERIAL PRIMARY KEY, name TEXT NOT NULL, salary NUMERIC );

CREATE TABLE employees_audit ( id SERIAL PRIMARY KEY, employee_id INT, old_salary NUMERIC, new_salary NUMERIC, changed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP );

CREATE OR REPLACE FUNCTION audit_salary_change() RETURNS TRIGGER AS $$ BEGIN IF OLD.salary IS DISTINCT FROM NEW.salary THEN INSERT INTO employees_audit (employee_id, old_salary, new_salary) VALUES (OLD.id, OLD.salary, NEW.salary); END IF; RETURN NEW; END; $$ LANGUAGE plpgsql;

CREATE TRIGGER trg_audit_salary AFTER UPDATE ON employees FOR EACH ROW EXECUTE FUNCTION audit_salary_change(); ```

Пример 2: Проверка данных (Oracle)

``sql CREATE OR REPLACE TRIGGER check_order_date BEFORE INSERT ON orders FOR EACH ROW BEGIN IF :NEW.order_date > SYSDATE THEN RAISE_APPLICATION_ERROR(-20001, 'Дата заказа не может быть в будущем'); END IF; END; ``

Критика и ограничения

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

  • Скрытая логика — триггеры выполняются автоматически, что может затруднить отладку и понимание поведения системы. Разработчики могут не знать о существовании триггера, что приводит к неожиданным побочным эффектам.
  • Производительность — построчные триггеры на больших объёмах данных (например, массовые UPDATE) могут значительно замедлить выполнение операций.
  • Сложность тестирования — триггеры сложно тестировать изолированно, так как они зависят от состояния базы данных и последовательности операций.
  • Рекурсия — триггеры могут вызывать другие триггеры, что приводит к каскадным вызовам и потенциальным бесконечным циклам. Большинство СУБД имеют ограничения на глубину рекурсии (например, в PostgreSQL — max_stack_depth).
  • Переносимость — синтаксис и возможности триггеров сильно различаются между СУБД, что затрудняет миграцию приложений.

Интересные факты

  • В СУБД SQLite триггеры поддерживаются с версии 3.0.0 (2004), но не поддерживают операторные триггеры (только построчные).
  • В стандарте SQL:2016 триггеры были расширены поддержкой триггеров на события DDL (CREATE, ALTER, DROP).
  • В России триггеры активно используются в системах электронного документооборота, например, в «1С:Документооборот» и «Дело» (АО «ЭОС»), для автоматического обновления статусов документов.
  • Некоторые СУБД (например, MySQL) не поддерживают триггеры BEFORE и AFTER одновременно на одной таблице для одного события.

Источники

  • ISO/IEC 9075-2:2016 — Information technology — Database languages — SQL — Part 2: Foundation (SQL/Foundation).
  • PostgreSQL Documentation, Chapter 41. Triggers.
  • Oracle Database SQL Language Reference, 19c, CREATE TRIGGER.
  • Microsoft SQL Server Documentation, CREATE TRIGGER (Transact-SQL).
  • MySQL 8.0 Reference Manual, Chapter 25.3. Using Triggers.
  • К. Дж. Дейт. Введение в системы баз данных. — 8-е изд. — М.: Вильямс, 2005. — 1328 с.
  • Г. Гарсиа-Молина, Дж. Ульман, Дж. Уидом. Системы баз данных. Полный курс. — М.: Вильямс, 2003. — 1088 с.

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →