2008-09-01 126 views
25

跟踪数据库表中更改的最佳方式是什么?如何跟踪数据库表中的数据更改

想象一下,您有一个应用程序,用户(在应用程序的上下文中不是DB用户)能够更改存储在某个数据库表中的数据。跟踪所有更改历史记录的最佳方法是什么,以便您可以显示哪个用户在什么时间更改哪些数据如何?

+2

一些很好的讨论:http://discuss.joelonsoftware.com/default.asp?design.4.483891 .10 – 2011-03-14 04:32:37

+0

另请参见[更新日志/审计数据库表的最佳设计?](https://stackoverflow.com/questions/201527/best-design-for-a-changes-auditing-database-table) – user 2017-09-14 07:51:20

回答

3

通常,如果您的应用程序被构建为图层,请让数据访问层调用数据库服务器上的存储过程以编写数据库更改的日志。

在支持这种事情的语言中,aspect-oriented programming可以是用于这类应用程序的一种很好的技术。审计数据库表更改是您通常希望记录所有操作的操作类型,所以AOP可以很好地工作。

请记住,日志记录数据库更改会创建大量数据,并会降低系统速度。根据应用程序的大小,使用消息队列解决方案和单独的数据库执行审计日志可能是明智的。

使用存储过程来处理这个问题也是完全可行的,尽管可能有一些工作需要将用户凭证传递给数据库本身。

+1

看起来像如果您希望允许用户查看自己的历史记录或其他人的历史记录,则他们无法访问日志文件。 – 2011-03-14 04:15:03

3

你在这里有几个问题没有很好地相互关联。

在基本数据库级别,您可以通过使用单独的表来获取通过INSERT/UPDATE/DELETE语句上的触发器添加的条目来跟踪更改。这就是跟踪对数据库表进行更改的一般方法。

你想要的另一件事是知道哪个用户作出了改变。通常你的触发器不会知道这一点。我假设如果你想知道哪个用户改变了一段数据,那么可能有多个用户可以改变相同的数据。

没有正确的方法来做到这一点,你可能希望有一个单独的表,即当用户更新其他表中的某些数据时,应用程序代码将插入一条记录,包括用户,时间戳和ID改变的记录。

确保使用一个事务,以便最终不会发生无需插入即可完成更新的情况,或者如果您执行的是相反的顺序,则不会在没有更新的情况下插入。

0

跟踪日志在一个单独的表(带ID列,可能带有时间戳)?

你是否想要撤消更改 - 也许预先创建撤消语句(每个INSERT的DELETE,每个正常UPDATE的(un-)UPDATE)并将其保存在跟踪中?

4

我经常见到的一种方法是有审计表。然后,您可以显示已更改内容,更改内容以及更改内容,或者任何您想要的内容。然后,您可以编写一个触发器来执行实际日志记录。如果正确完成,不要太痛苦......

不管你怎么做,它的种类取决于你的用户如何连接到数据库。他们是通过应用程序中的安全上下文使用单个应用程序用户吗?他们是使用自己的域帐户连接的,还是应用程序只让每个人都使用通用的SQL帐户连接?

如果您无法从数据库连接中获取用户信息,那会更加痛苦。然后你可以看看在应用程序中进行日志记录,所以如果你有一个叫做“CreateOrder”的进程或者其他的东西,你可以登录到Order_Audit表或者其他的东西。

在应用程序内部完成所有这些操作,可以让您从应用程序外部进行更改,但如果您有多个应用程序全都使用相同的数据,而您只是想查看您的更改是什么这就是你想要的... < 耸肩>

虽然祝你好运!

--Kevin

1

在研究这个同样的问题,我发现了一个讨论here非常有用的。它建议设置一个用于跟踪更改的并行表,其中每个更改跟踪表都具有与正在跟踪的列相同的列,以及由谁更改列的时间,以及是否已删除列。 (这应该是可能产生的架构对于更或多或少自动使用您预先存在的脚本的regexed后续版本。)

0

让我们尝试用这个开源组件:

https://tabledependency.codeplex.com/

TableDependency是一个通用的C#组件,用于在指定数据库表的内容更改时接收通知。

-1

如果所有的变化都来自php。您可以使用class在查询之前记录evry INSERT/UPDATE/DELETE。这将是节省行动NEWVALUE属性oldValue日期系统(如果需要), ipUserAgent的clumnReferenceoperatorReferencevalueReference。所有需要记录的表/列/动作都是可配置的。

1

假设我有一个包含PersonSid和UpdateDate的10列的人员表。现在,我想跟踪人员表中的任何更新。 这里是简单的技术我使用:

  1. 创建person_log表

    创建表person_log(日期DATETIME2,SID INT);

  2. 创建人上表中的触发器将插入一行到person_log表每当Person表得到更新:

    上dbo.Person
    创建触发器TR的更新
    作为 INSERT INTO person_log(日期, SID)从插入

选择updatedDTTM,personSID任何更新后,查询person_log表,你将能看到更新得到了personSid。 与插入,删除相同。

上面的例子是SQL,让我知道任何疑问的情况下,或使用此链接:这里 http://www.4guysfromrolla.com/webtech/042507-1.shtml