Mysql-如何查询过去(时光倒流)?
我有一个数据库,它总是在变化。。。更新、插入和删除。 出于统计原因,我们需要一些时间“回到过去”(:像过去一样查询数据库) 例如: 我有一个名为Mysql-如何查询过去(时光倒流)?,mysql,audit,Mysql,Audit,我有一个数据库,它总是在变化。。。更新、插入和删除。 出于统计原因,我们需要一些时间“回到过去”(:像过去一样查询数据库) 例如: 我有一个名为user的表,我昨天更新了其中一个用户,如下所示: update user set status = 1 where user_id = 2656 旧的状态为0,因此如果我可以“返回时间”到昨天并查询它,我将获得状态0,如果我现在查询它,我将获得状态1。 我知道一种方法是触发update、insert和delete,并将其记录到不同的表中,但它不是那么
user
的表,我昨天更新了其中一个用户,如下所示:
update user set status = 1 where user_id = 2656
旧的状态
为0,因此如果我可以“返回时间”到昨天并查询它,我将获得状态
0,如果我现在查询它,我将获得状态
1。我知道一种方法是触发update、insert和delete,并将其记录到不同的表中,但它不是那么干净,并且会使开发变得复杂 我希望你说对了,不是那么简单的解释给一个不会说英语的人 编辑-1
我们在应用程序中很少有算法,我们总是修复和升级它们,我们必须知道数据库在过去是如何的,这样我们才能处理算法,我们有可以更改的查询/接口来支持这一点(我知道这不是一个一周的项目,我们有足够的资源) 实际上,OLTP数据库的“时间机器”通常使用数据仓库来实现 你只需要包含最新的数据,这样你的应用程序就可以工作了。用历史数据填充它确实会污染模式,减慢它的速度,使它更复杂,等等 您的数据库将包含大量数据,但不需要接受频繁写入。相反,您可以使用它生成报告、分析趋势、进行预测。它是一个读优化的系统。实际上,OLTP数据库的“时间机器”通常使用数据仓库来实现 你只需要包含最新的数据,这样你的应用程序就可以工作了。用历史数据填充它确实会污染模式,减慢它的速度,使它更复杂,等等
您将包含大量数据,但不需要接受频繁写入。相反,您可以使用它生成报告、分析趋势、进行预测。它是一个读优化的系统。选项1启用二进制日志。
这将保护所有更新、插入和删除。
有用于binlog的查询工具 请参阅:
选项2创建保存更改的触发器
触发器将数据保存到与原始数据库布局相同的Parallel数据库中,但所有表都有两个额外字段。一个名为
log\u id
的unqiue id和一个时间戳。每当字段更改时,您都会在日志中记录触发器日志。您至少需要一个after_update和after_delete触发器,我建议您也使用after_insert触发器。如果您愿意,可以为每个名为
操作的表添加第三个字段,这是一个枚举('insert','delete','update')
DELIMITER $$
CREATE TRIGGER au_table1_each AFTER UPDATE ON table1 FOR EACH ROW
BEGIN
insert into back_to_the_past.table1_log (`timestamp`,operation,f1,f2,f3.f4)
values (now(), 'update', OLD.f1, OLD.f2, OLD.f3, OLD.f4);
END $$
DELIMITER ;
当然,如果您在table1\u log
中创建了一个额外的时间戳类型字段,则无需将其显式地添加到now()
数据库即可
请参阅:选项1启用二进制日志
这将保护所有更新、插入和删除。
有用于binlog的查询工具
请参阅:
选项2创建保存更改的触发器
触发器将数据保存到与原始数据库布局相同的Parallel数据库中,但所有表都有两个额外字段。一个名为log\u id
的unqiue id和一个时间戳。每当字段更改时,您都会在日志中记录触发器日志。
您至少需要一个after_update和after_delete触发器,我建议您也使用after_insert触发器。如果您愿意,可以为每个名为操作的表添加第三个字段,这是一个枚举('insert','delete','update')
DELIMITER $$
CREATE TRIGGER au_table1_each AFTER UPDATE ON table1 FOR EACH ROW
BEGIN
insert into back_to_the_past.table1_log (`timestamp`,operation,f1,f2,f3.f4)
values (now(), 'update', OLD.f1, OLD.f2, OLD.f3, OLD.f4);
END $$
DELIMITER ;
当然,如果您在table1\u log
中创建了一个额外的时间戳类型字段,则无需将其显式地添加到now()
数据库即可
请参阅:如果您有您所说的资源,我建议您购买一个SAN,并将MySQL数据文件放在虚拟磁盘上。在您想要的任何时间设置该磁盘的增量快照
每当您需要查找一些历史数据时,您都可以基于其中一个快照创建一个新的虚拟磁盘
这种方法不会给你一个连续的时间线,所以如果需要,你应该忽略这个建议…如果你有你所说的资源,我建议你自己买一个SAN,把你的MySQL数据文件放在一个虚拟磁盘上。在你想要的任何时间设置该磁盘的增量快照
每当您需要查找一些历史数据时,您都可以基于其中一个快照创建一个新的虚拟磁盘
这种方法不会给你一个连续的时间线,因此如果需要,你应该忽略这个建议…显示你的表格,以及你到目前为止所做的尝试?我个人认为这是一个相当糟糕的主意。如果你需要更改大量数据,你将需要某种类型的界面。此外,如果你将0
更改为1
,同样,将1
更改为0
也很容易。我不明白您为什么需要类似“时间机器”的功能。@JamWaffles、@DhruvPathak、@Robin Castlin-我编辑了这个问题(请参阅Edit-1)感谢MySQL(或据我所知的任何其他SQL服务器)中没有“查询过去”的方法。你唯一的选择是实施某种备份或审计跟踪系统。一旦你接受了这一点,你就有很多选择…@Ivar,你显然从来没有听说过二进制日志,否则你就会知道你所说的是胡说八道。展示你的表,以及你迄今为止所做的尝试。我个人认为这是一只老鼠H