Приходилось ли реализовывать триггеры в базах данных?

Ответ

Триггеры — это хранимые процедуры, автоматически выполняемые при наступлении событий (INSERT, UPDATE, DELETE) в таблице.

Основные сценарии использования:

  1. Аудит и логирование: Запись изменений в отдельную таблицу.
  2. Валидация данных: Проверка сложных бизнес-правил перед операцией.
  3. Поддержание целостности: Каскадные изменения в связанных таблицах.

Пример триггера в PostgreSQL для аудита:

CREATE TABLE audit_log (
    id SERIAL PRIMARY KEY,
    table_name VARCHAR(100),
    operation VARCHAR(10),
    old_data JSONB,
    new_data JSONB,
    changed_at TIMESTAMP DEFAULT NOW()
);

CREATE OR REPLACE FUNCTION log_user_changes()
RETURNS TRIGGER AS $$
BEGIN
    INSERT INTO audit_log (table_name, operation, old_data, new_data)
    VALUES ('users', TG_OP, to_jsonb(OLD), to_jsonb(NEW));
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER users_audit_trigger
AFTER INSERT OR UPDATE OR DELETE ON users
FOR EACH ROW EXECUTE FUNCTION log_user_changes();

Лучшие практики:

  • Избегайте сложной логики: Триггеры должны быть простыми, иначе они замедляют операции.
  • Учитывайте рекурсию: Триггеры могут вызывать сами себя.
  • Тестирование: Тщательно тестируйте, так как ошибки в триггерах влияют на все связанные операции.

Альтернативы: Часть логики можно перенести в прикладной код для упрощения отладки и миграций.

Ответ 18+ 🔞

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

Триггеры — это по сути такие хранимые процедуры-прилипалы, которые база сама запускает, когда случается какое-то событие: INSERT, UPDATE или DELETE. Автоматически, блядь, без твоего ведома!

Зачем они, эта хитрая жопа, вообще нужны?

  1. Аудит и логирование: Чтобы потом, когда всё накроется медным тазом, можно было посмотреть, кто, когда и какую хуйню в данные вписал. Записывают все изменения в отдельную таблицу-доносчика.
  2. Валидация данных: Ну там, проверить какое-нибудь ебучье бизнес-правило, которое в обычный CHECK не впихнуть. Типа «зарплата начальника отдела не может быть меньше, чем средняя зарплата по его отделу, иначе все уйдут нахуй».
  3. Поддержание целостности: Сделать каскадное обновление или удаление там, где FOREIGN KEY с каскадом не справляется или слишком тупой.

Смотри, как это выглядит на практике, ёпта. Допустим, нам нужно следить за таблицей users:

Сначала создаём таблицу для стукачей:

CREATE TABLE audit_log (
    id SERIAL PRIMARY KEY,
    table_name VARCHAR(100),
    operation VARCHAR(10),
    old_data JSONB,
    new_data JSONB,
    changed_at TIMESTAMP DEFAULT NOW()
);

А теперь саму функцию-триггер, которая будет в эту таблицу доносить:

CREATE OR REPLACE FUNCTION log_user_changes()
RETURNS TRIGGER AS $$
BEGIN
    INSERT INTO audit_log (table_name, operation, old_data, new_data)
    VALUES ('users', TG_OP, to_jsonb(OLD), to_jsonb(NEW));
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

И вешаем этого стукача на таблицу users:

CREATE TRIGGER users_audit_trigger
AFTER INSERT OR UPDATE OR DELETE ON users
FOR EACH ROW EXECUTE FUNCTION log_user_changes();

Вот и всё! Теперь любое изменение в users будет тупо логироваться. Красота, да? А главное — автоматически, волнение ебать!

Но, чувак, осторожно, это не конфетка:

  • Не делай их слишком умными. Если в триггере будет овердохуища сложной логики, то каждая операция с таблицей будет тормозить, как черепаха в сиропе. Простота — наше всё.
  • Следи за рекурсией. Может получиться так, что триггер на таблице А меняет таблицу Б, а у той свой триггер меняет обратно таблицу А... И поехали, пиздец, бесконечный цикл, база ляжет и будет плакать.
  • Тестируй, как последний уёбок. Ошибка в триггере — это не просто ошибка в одном запросе. Это пиздец всему, что пытается работать с этой таблицей. Всё падает, все орут.

Альтернативы? Да похуй, конечно есть! Часть этой логики можно запихнуть в код приложения. Так хоть отлаживать проще и миграции делать не так страшно. Но иногда триггер — это именно то, что надо, этакая хитрая жопа прямо в недрах базы. Главное — не переборщить, а то сам потом будешь ебаться с этой своей «гениальной» автоматизацией.