Ответ
Триггер (Trigger) — это специальная хранимая процедура в СУБД, которая автоматически выполняется (срабатывает) при наступлении определенного события с таблицей: INSERT, UPDATE или DELETE. Триггеры привязаны к таблице и позволяют реализовать сложную бизнес-логику и поддержание целостности данных непосредственно на уровне БД.
Типичные сценарии использования:
-
Аудит и логирование изменений:
CREATE TRIGGER audit_employee_update AFTER UPDATE ON Employees FOR EACH ROW BEGIN INSERT INTO AuditLog (table_name, record_id, action, old_value, new_value, changed_at, changed_by) VALUES ('Employees', OLD.id, 'UPDATE', OLD.salary, NEW.salary, CURRENT_TIMESTAMP, USER()); END;Здесь
OLDиNEW— псевдонимы для строк до и после изменения. -
Поддержание денормализованных данных или вычисляемых полей:
CREATE TRIGGER update_order_total AFTER INSERT ON OrderItems FOR EACH ROW BEGIN UPDATE Orders SET total_amount = ( SELECT SUM(quantity * price) FROM OrderItems WHERE order_id = NEW.order_id ) WHERE id = NEW.order_id; END; -
Сложная валидация, которую нельзя выразить через
CHECK:CREATE TRIGGER validate_salary BEFORE INSERT ON Employees FOR EACH ROW BEGIN IF (NEW.salary > (SELECT avg_salary * 2 FROM Department WHERE id = NEW.department_id)) THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Salary exceeds department limit'; END IF; END;
Важные особенности и недостатки:
- Прозрачность: Логика в триггерах скрыта от прикладного кода, что может усложнить отладку.
- Производительность: Каждая операция с таблицей несет дополнительную нагрузку от выполнения триггера.
- Каскадное срабатывание: Триггер может модифицировать другую таблицу, в которой тоже есть триггер, что может привести к цепочке вызовов.
- Порядок: В некоторых СУБД можно задавать порядок выполнения нескольких триггеров на одно событие.
Итог: Триггеры — мощный, но требующий осторожного применения инструмент для реализации логики, критичной к целостности данных, непосредственно в БД.
Ответ 18+ 🔞
Слушай, вот объясню тебе про триггеры, как есть. Представь себе, что твоя база данных — это такой склад, а таблицы — это полки. Триггер — это, блядь, злой гном-надзиратель, который привязан к конкретной полке и сидит на ней, не спит. И как только ты пытаешься что-то на этой полке сделать — положить новую коробку (INSERT), переставить старую (UPDATE) или, не дай бог, выкинуть нахуй (DELETE) — этот гном сразу выпрыгивает и начинает свою волшебную хуйню. Автоматически, сам, без твоего ведома. Вот это и есть триггер, ёпта.
Где эта мартышлюшка может пригодиться?
-
Шпионить за всеми, как стукач. Допустим, кто-то полез в таблицу зарплат (
Employees) и поправил себе цифры. А гном-триггер уже тут как тут, всё видит и записывает в отдельную чёрную книжку (AuditLog), кто, когда и сколько украл.CREATE TRIGGER audit_employee_update AFTER UPDATE ON Employees FOR EACH ROW BEGIN INSERT INTO AuditLog (table_name, record_id, action, old_value, new_value, changed_at, changed_by) VALUES ('Employees', OLD.id, 'UPDATE', OLD.salary, NEW.salary, CURRENT_TIMESTAMP, USER()); END;Видишь
OLDиNEW? Это как фотки «было» и «стало». Гном их сравнивает и доносит, хитрая жопа. -
Поддерживать порядок, потому что все вокруг распиздяи. Добавили новую позицию в заказ (
OrderItems)? Ну ясное дело, общая сумма заказа (Orders.total_amount) теперь не бьётся. А гном уже побежал её пересчитать и поправить, чтобы всё было ажуре.CREATE TRIGGER update_order_total AFTER INSERT ON OrderItems FOR EACH ROW BEGIN UPDATE Orders SET total_amount = ( SELECT SUM(quantity * price) FROM OrderItems WHERE order_id = NEW.order_id ) WHERE id = NEW.order_id; END;Удобно? Удобно. Потому что иначе пришлось бы это делать в коде приложения, а там программисты могут и забыть, или накосячить.
-
Быть строгим вышибалой, когда встроенных правил (
CHECK) не хватает. Хочет менеджер вписать себе зарплату в два раза выше средней по отделу? Гном-триггер типаBEFORE INSERTего нахуй пошлёт с ошибкой, даже не дав записать эту поебень.CREATE TRIGGER validate_salary BEFORE INSERT ON Employees FOR EACH ROW BEGIN IF (NEW.salary > (SELECT avg_salary * 2 FROM Department WHERE id = NEW.department_id)) THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Salary exceeds department limit'; END IF; END;
Но не всё так гладко, чувак. Есть и подводные ебушки-воробушки:
- Невидимка. Вся логика спрятана в недрах БД. Смотришь на красивый код приложения
app.saveEmployee(), а откуда там берутся логи или почему сумма пересчиталась — нихуя не понятно. Надо лезть в схему базы и искать этого гнома. Доверия ебать ноль к такой системе, если ты её не проектировал. - Тормоз. Каждое действие на полке теперь — это не просто действие, а ещё и выступление гнома с хуевой магией. Если триггер тяжелый, то вся система будет ебаться как черепаха.
- Цепная реакция. Гном из триггера полез что-то поправить в другой таблице. А там сидит ещё один гном, который тоже срабатывает. И понеслась… Может получиться такая каскадная пиздопроебильня, что сервак просто накроется медным тазом.
- Очередь. Если на одну полку навешано пять гномов на одно событие, то важно, в каком порядке они будут прыгать. А это ещё тот геморрой.
Итог, блядь. Триггеры — это овердохуища мощный инструмент, когда нужно железно гарантировать какое-то правило прямо в базе, чтобы никакой идиотский код приложения не мог его обойти. Но юзать их нужно с умом, а то получится манда с ушами: вроде логика есть, а разобраться, кто и где срабатывает, — нихуя невозможно. Э, бошка, думай, прежде чем плодить этих невидимых гномов.