Я стараюсь сохранить историю каждого обновления таблиц в моем приложении. Я использую Laravel, я знаю, что есть какой-то пакет, который может мне помочь, но я ищу что-то чистое и быстрое.
У меня есть два варианта:
Мой первый вопрос: какой из них быстрее?
Мой второй вопрос:
я должен использовать такую схему и сохранить в ней все свои таблицы:
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 ...
Учитывая эту схему:
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');
Это дизайнерское решение, поэтому оно действительно зависит от вас и ваших требований. У вас есть следующие вещи для рассмотрения:
Если пользователь изменяет запись в транзакции, все затронутые поля будут изменены одним и тем же пользователем одновременно. С вашей предложенной структурой все эти изменения потребуют отдельной записи.
С вашей предложенной структурой сложнее определить, как выглядела определенная запись в данный момент времени, поскольку вам в основном приходится воспроизводить все изменения этой записи с момента ее вставки.
Что касается профессионалов, все изменения хранятся в одной таблице, и даже если вы измените схему базы данных, вам не нужно менять структуру ведения журнала.
Вы также должны решить, хотите ли вы регистрировать изменения всех таблиц или только некоторые из них.
Вы также должны рассмотреть, как вы регистрируетесь, если регистрируемая таблица ссылается на другие таблицы. Например, если вы хотите регистрировать транзакции, то у вас может быть поле типа транзакции и отдельная таблица типов транзакций со списком подробных описаний и, возможно, другой информацией о каждом типе транзакции. Если тип транзакции больше не используется, его можно удалить из таблицы типов транзакций или ее параметры могут измениться.