MySQL Trigger или PHP для аудита данных?

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

У меня есть два варианта:

  • MySQL Trigger
  • Через код PHP

Мой первый вопрос: какой из них быстрее?

Мой второй вопрос:
я должен использовать такую ​​схему и сохранить в ней все свои таблицы:

CREATE TABLE revisions (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`revisionable_type` VARCHAR(255) NOT NULL COLLATE 'utf8_unicode_ci',
`revisionable_id` INT(11) NOT NULL,
`user_id` INT(11) NULL DEFAULT NULL,
`key` VARCHAR(255) NOT NULL COLLATE 'utf8_unicode_ci',
`old_value` TEXT NULL COLLATE 'utf8_unicode_ci',
`new_value` TEXT NULL COLLATE 'utf8_unicode_ci',
`created_at` TIMESTAMP NULL DEFAULT NULL,
`updated_at` TIMESTAMP NULL DEFAULT NULL
)

Или я должен воссоздать «дубликат» каждой таблицы, такой как user_history, и добавить историю в соответствующие столбцы

Users: id, name, surname ...
Users_history: id, user_id, name, surname ...

0

Решение

Учитывая эту схему:

CREATE TABLE contacts (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`first_name` VARCHAR(255) NOT NULL COLLATE 'utf8_unicode_ci',
`last_name` VARCHAR(255) NOT NULL COLLATE 'utf8_unicode_ci',
`updated_by` VARCHAR(255) NOT NULL COLLATE 'utf8_unicode_ci',
`updated_at` TIMESTAMP NULL DEFAULT NULL
)

Я бы также создал эту схему:

CREATE TABLE contacts_audit (
`id` INT(10) UNSIGNED NOT NULL,
`first_name` VARCHAR(255) NOT NULL COLLATE 'utf8_unicode_ci',
`last_name` VARCHAR(255) NOT NULL COLLATE 'utf8_unicode_ci',
`updated_by` VARCHAR(255) NOT NULL COLLATE 'utf8_unicode_ci',
`updated_at` TIMESTAMP NULL DEFAULT NULL,
`action` varchar(255) NOT NULL COLLATE 'utf8_unicode_ci'
)

Затем используйте эти триггеры (надеюсь, мой синтаксис триггера не слишком ржавый):

CREATE TRIGGER contacts_audit_insert
AFTER INSERT
ON users FOR EACH ROW
BEGIN
INSERT INTO contacts_audit (id, first_name, last_name, updated_by, updated_at, action) values (NEW.id, NEW.first_name, NEW.last_name, NEW.updated_by, NEW.updated_at, 'insert');
END;

CREATE TRIGGER contacts_audit_update
AFTER UPDATE
ON users FOR EACH ROW
BEGIN
INSERT INTO contacts_audit (id, first_name, last_name, updated_by, updated_at, action) values (NEW.id, NEW.first_name, NEW.last_name, NEW.updated_by, NEW.updated_at, 'update');
END;

CREATE TRIGGER contacts_audit_delete
BEFORE DELETE
ON users FOR EACH ROW
BEGIN
INSERT INTO contacts_audit (id, first_name, last_name, updated_by, updated_at, action) values (OLD.id, OLD.first_name, OLD.last_name, OLD.updated_by, OLD.updated_at, 'delete');
END;

Потенциальные недостатки

Если вы используете одно имя пользователя / пароль MySQL для доступа к базе данных и аутентификации своих пользователей по users Затем в MySQL перед выполнением каких-либо удалений вы захотите выполнить обновление в PHP, а затем удалить, чтобы вы могли определить, кто удалил вашу запись.

Однако, если вы используете MySQL для аутентификации всех пользователей, вы можете использовать это в своих триггерах: обратите внимание на использование USER()

INSERT INTO contacts_audit (id, first_name, last_name, updated_by, updated_at, action) values (NEW.id, NEW.first_name, NEW.last_name, USER(), NEW.updated_at, 'insert');
0

Другие решения

  1. Время оба решения, и вы увидите, какое из них работает быстрее для вас. Невозможно сказать, что будет быстрее в вашем приложении и среде.
  2. Это дизайнерское решение, поэтому оно действительно зависит от вас и ваших требований. У вас есть следующие вещи для рассмотрения:

    • Если пользователь изменяет запись в транзакции, все затронутые поля будут изменены одним и тем же пользователем одновременно. С вашей предложенной структурой все эти изменения потребуют отдельной записи.

    • С вашей предложенной структурой сложнее определить, как выглядела определенная запись в данный момент времени, поскольку вам в основном приходится воспроизводить все изменения этой записи с момента ее вставки.

    • Что касается профессионалов, все изменения хранятся в одной таблице, и даже если вы измените схему базы данных, вам не нужно менять структуру ведения журнала.

    • Вы также должны решить, хотите ли вы регистрировать изменения всех таблиц или только некоторые из них.

    • Вы также должны рассмотреть, как вы регистрируетесь, если регистрируемая таблица ссылается на другие таблицы. Например, если вы хотите регистрировать транзакции, то у вас может быть поле типа транзакции и отдельная таблица типов транзакций со списком подробных описаний и, возможно, другой информацией о каждом типе транзакции. Если тип транзакции больше не используется, его можно удалить из таблицы типов транзакций или ее параметры могут измениться.

1

По вопросам рекламы [email protected]