如何跟踪参考表的历史变化?

时间:2012-04-10 03:32:30

标签: sql oracle history

这在Web应用程序中非常常见。如果我有一个用户表,并且我想跟踪对用户表所做的所有更改,我可以使用数据库插入和更新触发器将这些更改保存在user_history表中。

但是如果我有user_products表,我有user_id,product_id,cost。当我在系统中添加用户时,可以说我有两个与该用户关联的产品。所以我的user_products表将为该用户提供两行。

user_id product_id cost
1       10         1000
2       20         2000

现在,如果我转到编辑用户页面并删除产品1,请添加产品3,将产品2的成本从2000更改为3000.

通常我会从user_product表中删除user_id 1的所有记录,然后为新产品执行新的插入。

所以它不是常规更新,而是删除然后插入。因此,我无法跟踪历史变化。

理想情况下,我想知道我删除了产品1,添加了产品3,将产品2的成本从2000改为3000.

编辑1: -

我没有做更新。我正在删除然后插入。因此我删除了产品ID为2且成本为2000的记录。然后再次插入带有prod id 2但成本为3000的记录。所以从技术上来说它的删除和插入但逻辑上只有成本从2000变为3000.如果我检查同时执行两者查询它会说我删除了ID为2的产品,然后添加了id为2的相同产品。但我希望能够看到成本从2000到3000

2 个答案:

答案 0 :(得分:4)

一个选项是创建一个由user_product_history上的触发器填充的user_product表,然后定义一个触发器,将历史记录表中的旧“删除”行转换为{{1}如果随后插入了行。

update

然而,从效率的角度来看,删除和插入而不是更新将意味着您在数据库上的负载超出了必要的范围。您将完成比必要更多的I / O.而且最终会有更复杂的代码来处理更改。你几乎肯定会更好地找出已经改变的东西,然后只是更新那些行。

答案 1 :(得分:1)

我不知道是否有“标准”方式或简单方式,但根据我的经验,你必须自己做... 当然,您不需要为每个表编写特定的方法,而是需要处理所有更新SQL的通用方法,根据您的表结构,这是一种智能方法。 例: 您可以定义将具有以下内容的历史记录表: id - 表名 - 表记录id - 要更新的字段列表 - 更新的值列表BEFORE - 更新后的值列表

然后,在您的代码中,您应该有一个将处理SQL查询的抽象类:在更新时,您调用将解析SQL查询并将记录插入此表的方法,即使您必须查询SELECT在更新之前检索数据(开销最小,因为SELECT只使用少量资源,您可以使用DB服务器缓存)。 最后,当您显示与记录相关的信息时,假设用户,您可以添加代码以显示此表上的历史记录和此用户ID。

希望它会对你有所帮助。