跟踪数据库表中更改的最佳方法是什么?
想象一下,您有一个应用程序,其中用户(在应用程序的上下文中而不是数据库用户)能够更改存储在某个数据库表中的数据。跟踪所有更改历史记录的最佳方法是什么,以便您可以显示哪个用户在何时更改哪些数据?
答案 0 :(得分:5)
我经常看到的一种方法是拥有审计表。然后你可以显示改变了什么,改变了什么,改变了什么,或者你想要的任何东西:)然后你可以编写一个触发器来进行实际的记录。如果做得不好也不会太痛苦......
无论您如何操作,都取决于您的用户如何连接到数据库。他们是通过应用程序中的安全上下文使用单个应用程序用户,是使用域中的自己的帐户进行连接,还是应用程序只是让所有人都使用通用sql帐户进行连接?
如果您无法从数据库连接获取用户信息,那就更难了。然后你可能会看看在应用程序中进行日志记录,所以如果你有一个名为“CreateOrder”的进程或其他什么,你可以登录Order_Audit表或其他任何内容。
在应用程序中完成所有操作可以让您自己更多地了解应用程序外部所做的更改,但是如果您有多个应用程序都使用相同的数据,而您只是想看看您的更改是什么,也许这就是你想要的......< 耸肩>
祝你好运!
- 凯文
答案 1 :(得分:4)
通常,如果您的应用程序是分层结构,请让数据访问层调用数据库服务器上的存储过程来写入数据库更改的日志。
在支持此类事物的语言中aspect-oriented programming可以成为用于此类应用程序的好方法。审计数据库表更改是您通常要为所有操作记录的操作类型,因此AOP可以很好地工作。
请记住,记录数据库更改会产生大量数据,并会降低系统速度。根据应用程序的大小,使用消息队列解决方案和单独的数据库来执行审计日志可能是明智的。
使用存储过程来处理这个问题也是完全可行的,尽管可能需要做一些工作才能将用户凭据传递到数据库本身。
答案 2 :(得分:3)
你在这里遇到的一些问题并没有很好地相互关联。
在基本数据库级别,您可以通过使用单独的表来跟踪更改,该表通过INSERT / UPDATE / DELETE语句上的触发器添加一个条目。这是跟踪数据库表更改的一般方法。
您想要的另一件事是知道哪个用户进行了更改。通常你的触发器不会知道这一点。我假设如果你想知道哪个用户改变了一个数据,那么多个用户可能会改变相同的数据。
没有正确的方法来执行此操作,您可能希望有一个单独的表,当用户更新另一个表中的某些数据时,您的应用程序代码将插入记录,包括用户,时间戳和ID改变了记录。
确保使用一个事务,这样你就不会在没有插入的情况下完成更新的情况,或者如果你做相反的顺序,你最终不会在没有更新的情况下插入。
答案 3 :(得分:3)
在研究同样的问题时,我发现讨论here非常有用。它建议使用并行表集来跟踪更改,其中每个更改跟踪表具有与其跟踪的列相同的列,以及更改它的列,何时以及是否已删除。 (应该可以通过使用预先存在的脚本的regexed-up版本来自动生成这种模式。)
答案 4 :(得分:2)
假设我有一个包含10个列的Person表,其中包括PersonSid和UpdateDate。现在,我想跟踪Person Table中的任何更新。 这是我使用的简单技术:
创建person_log表
create table person_log(date datetime2,sid int);
在Person表上创建一个触发器,只要Person表更新,它就会在person_log表中插入一行:
在dbo.Person上创建触发器
更新
如
插入person_log(date,sid)选择updatedDTTM,插入的PersonSID
在任何更新之后,查询person_log表,您将能够看到更新的personSid。 与插入,删除相同。
以上示例适用于SQL,如有任何疑问或请使用此链接,请通知我: http://www.4guysfromrolla.com/webtech/042507-1.shtml
答案 5 :(得分:0)
单独表中的跟踪日志(带有ID列,可能带有时间戳)?
您是否也想要撤消更改 - 也许预先创建撤消语句(每个INSERT为DELETE,每个正常UPDATE为(un-)UPDATE)并将其保存在跟踪中?
答案 6 :(得分:0)
答案 7 :(得分:0)
如果所有的变化都来自php。在查询之前,您可以使用class来记录evry INSERT / UPDATE / DELETE。它将保存 操作 , 表 , 列 , newValue , oldValue , 日期 , 系统 (如果需要), ip , UserAgent , clumnReference , operatorReference , valueReference 。需要记录的所有表/列/操作都是可配置的。