Как сгруппировать изменения данных при работе с триггерами MySQL - PullRequest
1 голос
/ 08 февраля 2010

Я использую триггеры в MySQL для регистрации изменений данных. Эти изменения записываются на уровне строк. Теперь я могу вставить запись в мою таблицу журналов для каждой изменяемой строки. Однако мне также нужно записать операцию, к которой относятся изменения.

Например, операция удаления, такая как «DELETE * FROM table WHERE type = x», может удалить несколько строк. С помощью триггера я могу вставить запись для каждой удаленной строки в таблицу журнала, но я хотел бы также предоставить уникальный идентификатор для операции в целом, чтобы таблица журнала выглядела примерно так:

log_id  operation_id  tablename  fieldname  oldvalue  newvalue

1       1             table      id         1         null  
2       1             table      type       a         null
3       1             table      id         2         null
4       1             table      type       a         null
5       2             table      id         3         null  
6       2             table      type       b         null
7       2             table      id         4         null
8       2             table      type       b         null

Есть ли способ в MySQL идентифицировать операцию более высокого уровня, к которой относятся изменения строки? Или это возможно только с помощью кода прикладного уровня? В будущем было бы также неплохо иметь возможность записать транзакцию, к которой относится операция.

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

Когда это невозможно с MySQL, как это происходит с другими системами баз данных? Для текущего проекта это не вариант использовать что-то кроме MySQL, но было бы неплохо знать это для будущих проектов.

EDIT В псевдокоде я хотел бы получить следующий вид триггера:

CREATE TRIGGER tablename_log_insert
AFTER INSERT ON tablename
INSERT INTO log_operations (operation_type, relation) VALUES ('insert', 'tablename');
SET @operation_id = LAST_INSERT_ID();
FOR EACH ROW
BEGIN
    INSERT INTO log_tablename(@operation_id, ...) VALUES (@operation_id, ...);
END;

Я знаю, что это неправильно для MySQL, но, возможно, этот псевдокод поможет прояснить мой вопрос.

Ответы [ 2 ]

1 голос
/ 07 апреля 2010

Основываясь на создании триггера, вы знаете, что такое контекст: удалить, вставить, обновить.

CREATE TRIGGER  <name_of_trigger>  
   [BEFORE | AFTER] 
   [UPDATE | INSERT | DELETE] -- Dictates context for trigger 'action'.
ON <table_name>
FOR EACH ROW BEGIN
  <SQL to execute>
END

Если вы добавите столбец 'action' в свой журнал, вы можете указать, какое действие было использовано для добавления записи в журнал 'change'.

Пример:

DELIMITER $$

-- Create Update,Insert,Delete triggers that logs the result of a table update to a log  
CREATE TRIGGER  trg_AFT_INS_table  AFTER UPDATE ON table
FOR EACH ROW BEGIN
  INSERT INTO table_log ( a, b, c, d, action)
  VALUES ( NEW.a, NEW.b, NEW.c, NEW.d, "update");
END $$
CREATE TRIGGER  trg_AFT_INS_table  AFTER INSERT ON table
FOR EACH ROW BEGIN
  INSERT INTO table_log ( a, b, c, d, action)
  VALUES ( NEW.a, NEW.b, NEW.c, NEW.d, "insert");
END $$
CREATE TRIGGER  trg_AFT_INS_table  AFTER DELETE ON table
FOR EACH ROW BEGIN
  INSERT INTO table_log ( a, b, c, d, action)
  VALUES ( OLD.a, OLD.b, OLD.c, OLD.d, "delete");
END $$

Вы могли бы обсудить BEFORE vs AFTER при регистрации изменений таблицы ... Мы обнаружили, что использование значений after позволяет сделать журнал таким же, как и «двоичный журнал», и его можно использовать для восстановления, включая последняя модификация, таблица, для которой ведется регистрация.

- Дж. Йоргенсон -

0 голосов
/ 14 мая 2012

Используйте общий журнал запросов MySQL , который позволяет фиксировать точные операторы, которые были выполнены. Вы можете выбрать независимо от того, записано ли оно в файл или таблицу.

...