我使用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
设计来保持各种表的所有数据更改。有没有办法,教程,引擎,插件来做到这一点?只有我能想到制作每张桌子的副本并继续存储它们的变化,但我不认为它的好方法。
答案 0 :(得分:21)
我现在已经考虑了一段时间,只能想到两种方法。当制作成抽象数据层/模型时,两者都可以完全透明。
顺便说一句,有一个"版本化的实现" ORM映射器原则中的表数据。见example in their docs。也许这符合您的需求,但它并不适合我的需求。它似乎删除了原始记录被删除时的所有历史数据,使其不是真正的修订安全。
选项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 ..
语句,使用要回滚的修订版本中的数据。 优点:
如上所述,doctrines versionable
做了类似的事情。
选项B:有一个中央更改日志表
前言:不良做法,仅为替代例示。
这种方法很大程度上依赖于应用程序逻辑,应该隐藏在数据层/模型中。
您有一个跟踪
的中央历史记录表与其他方法一样,您可能还希望跟踪哪些单个数据更改属于单个用户操作/事务以及顺序。
优点:
优点:
<强>结论:强>
答案 1 :(得分:2)
使用一般的uni更新表怎么样?表字段应包含以下值:
user,event,date,table,field,new value
可以使用常规查询中的某些函数创建值和插入。