У меня есть система, написанная с использованием Codeigniter и как база данных с использованием MySQL. У системы есть пользователь, пользовательские группы с разными привилегиями и т. Д. Имеют много таблиц mysql, которые имеют много разных отношений.
Некоторые из таблиц, которые у меня есть:
В настоящее время я регистрирую каждое изменение данных для этих таблиц, сделанных пользователями. Пользователи могут изменять эти данные из-за своей привилегии. Сохранение изменений журналов только в простой форме, например
A user changed product features with id of A8767 B user added new customer with id 56 C user edited content of orderlist A user added new product (id: A8767) to order (id: or67) ...
Я хочу сохранить все изменения, которые были сделаны с каждой деталью, например, редактировать историю вопроса Stackoverflow. Я могу подумать о дизайне log_table
чтобы сохранить все изменения данных из разных таблиц. Есть ли способ, учебник, движок, плагин для этого? Только я могу думать о дублировании каждой таблицы и сохранять изменения на них, но я не считаю ее хорошим способом.
Я уже давно об этом подумал и могу думать только о двух способах этого. Оба могут работать полностью прозрачно при создании абстрактного слоя данных / модели.
Кстати, существует реализация для «версий» табличных данных в доктрине ORM mapper. См. Этот пример в своих документах . Возможно, это соответствует вашим потребностям, но это не подходит мне. Кажется, что все исторические данные удаляются, когда исходная запись удаляется, что делает ее действительно не безопасной.
Вариант A: иметь копию каждой таблицы для хранения данных ревизии
Допустим, у вас есть простая таблица контактов:
CREATE TABLE contact ( id INT NOT NULL auto_increment, name VARCHAR(255), firstname VARCHAR(255), lastname VARCHAR(255), PRIMARY KEY (id) )
Вы должны создать копию этой таблицы и добавить данные ревизии:
CREATE TABLE contact_revisions ( id INT NOT NULL, name VARCHAR(255), firstname VARCHAR(255), lastname VARCHAR(255), revision_id INT auto_increment, type ENUM('INSERT', 'UPDATE', 'DELETE') NOT NULL, change_time DEFAULT current_timestamp, PRIMARY KEY(revision_id) )
Следите за INSERT
и UPDATE
с помощью триггеров AFTER
. При каждой новой ревизии данных в оригинале вставьте копию новых данных в таблицу ревизий и правильно настройте type
изменения.
Чтобы зарегистрировать безопасный DELETE
вы также должны вставить новую строку в таблицу истории! Для этого вы должны использовать триггер BEFORE DELETE
и сохранять последние значения до их удаления. В противном случае вам придется удалить каждое ограничение NOT NULL
в таблице истории.
Некоторые важные замечания относительно этой реализации
UNIQUE KEY
(здесь: PRIMARY KEY
) из таблицы ревизий, потому что у вас будет один и тот же ключ несколько раз для каждой ревизии данных. ALTER
схему и данные в исходной таблице посредством обновления (например, обновление программного обеспечения), вы должны обеспечить, чтобы те же данные или схемы были применены к таблице истории и ее данным. В противном случае вы столкнетесь с проблемами при возврате к более старой версии набора записей. Выгоды:
INSERT .. ON DUPLICATE KEY UPDATE ..
в исходной таблице, используя данные из ревизии, которую вы хотите отменить. Существо дела:
Как уже говорилось выше, доктрины с versionable
делают что-то похожее.
Вариант B: иметь таблицу журналов центрального изменения
предисловие: плохая практика, показанная только для иллюстрации альтернативы.
Этот подход в значительной степени полагается на логику приложения, которая должна быть скрыта в слое / модели данных.
У вас есть таблица центральной истории, которая отслеживает
Как и в другом подходе, вы также можете отслеживать, какие изменения отдельных данных относятся к одному действию / транзакции пользователя и в каком порядке.
Выгоды:
Существо дела:
Вывод:
Как насчет использования общей таблицы обновления uni. Поля таблицы должны содержать следующие значения:
user,event,date,table,field,new value
Значения и вставка могут быть созданы с помощью некоторой функции из общего запроса.