数据库审计 - 跟踪并重建以前的结果

时间:2013-04-17 14:30:54

标签: sql database database-design

我有一个存储业务联系人和相关信息的表。

目前,每天都会在表格中保存所有联系人的副本。表结构如下所示:

Date        CompanyName          Description      Address        Industry
20130416    Alpha Corp           bla bla bal      6100 main st.  Finicial 

20130417    Alpha Corp           bla bla bal      6100 main st.  Finicial 
20130417    Beta Corp            bla bla bal      6500 main st.  Consumer

20130418    Alpha Corp           bla bla bal      6120 main st.  Finicial 
20130418    Beta Corp            bla bla bal      6500 main st.  Consumer

这说明当20130417“Beta Corp”被添加时,以及当20130418“Alpa corp”被修改时会发生什么。

我想将其更改为具有审计跟踪功能。 目前在我看来是一个存储所有当前条目的表(引入新字段CompanyID int auto-intrement)

CompanyID CompanyName Description Address Industry

另一个存储所有历史变化的表

CompanyID CompanyName Description Address Industry ChangeTime Action User

大多数查询都是为了获取今天的联系人列表,这在新架构下很容易,但我仍然希望能够执行“从20130416获取联系人列表”这样的查询,这些查询应该返回1排。通过当前条目和更改日志构建历史数据感觉相当脏。

在类似情况下你会做什么?和推理?

最佳,

4 个答案:

答案 0 :(得分:3)

审计跟踪通常会识别谁更改了内容。你正在寻找一些截然不同的东西。您希望数据库回答select * from table_name where (data appears as it did on 2013-01-15);等问题。

据我所知,Richard Snodgrass发表了最早使用SQL解决此类问题的综合性工作。他将面向时间的数据库(和表格)分解为这些类别。

  • 有效时间表:这些表格捕捉“不断变化的现实的历史。”
  • 交易时间表:这些表捕获“更改表的状态序列。”
  • 双时态表:这些表实现了有效的时间和事务时间表。

我认为你正在寻找双时间表。

他的书Developing Time-oriented database applications in SQL可以从他在亚利桑那大学的教师网页上获得,作为PDF下载。因为它是免费的,所以在你挖洞之前没有理由不偷它。请仔细阅读代码以了解完整性限制。 (弄错了,你的数据库几乎一文不值。)

答案 1 :(得分:0)

我使用过必须维护审计历史记录的数据库。为此,有一个名为“Timeframe ID”的字段。如果该字段的值为-1,则表示该记录是过去的。如果是0则记录是最新的。在某些情况下,它将是1意味着它是未来的记录(这些是罕见的)。

这些表还有一个“修改”的日期字段。因此,如果用户进行更新,您只需将当前的Timeframe 0记录更新为-1,然后插入包含已修改数据的新行。通过这种方式,您可以分辨出更改内容和时间的人或者,在您每天更新数据的情况下,修改日期将是记录加载的日期。

希望这有帮助。

答案 2 :(得分:0)

我认为你正走在正确的轨道上。我的建议是像你提议的那样拆分表格。

Travis的解决方案可能正常,但考虑到历史快照会随着时间的推移而变得非常大。如果您将它们分开,那么当天的查询将会快速运行。如果你把它们放在一起,随着时间的推移,查询会自然地变得越来越慢(授予它可能需要一段时间才能注意到)。

Travis的想法是将修订版ID与公司ID配对是好的。我以前称之为“快照”ID。我在表中有一个快照ID,然后是另一个表,其中包含我可以加入的快照的详细信息。

例如:

公司表:

CompanyID, CompanyName, Description, Address, Industry

公司历史表(快照ID和公司ID代表您的密钥):

SnapshotID, CompanyID, CompanyName, Description, Address, Industry

快照表:

SnapshotID, CreateDate, CreateDateTime

我强烈建议将创建快照的时间归零,以使查询更容易一些。如果他们真的只代表一天,那么时间就变成了烦恼。您仍然可以存储它以查看实际完成的时间。

答案 3 :(得分:0)

要考虑一些事情。首先,审计的目的是什么?审计与维护面向时间的数据不同。如果您正在审核,则需要信息才能撤消更改。因此,保存旧数据至关重要,但它对于保存更改发生的日期以及更改的应用程序或更改应用程序至关重要。这样,如果你在周三和周五发布了一个新版本的应用程序,就会发现一个错误,它改变了很多不应该改变的东西;你知道那个应用程序从星期五到星期五确切改变了哪些记录。轻松修复不良变化。真正的审计应始终通过触发器而不是应用程序来处理。

历史数据不同,你这样做是因为你需要知道某个时间点某事物的状态。对于订单详细信息表中的实例,您可能希望在订单时存储商品的价格,而不是一年后查询记录时的价格。在这种情况下,您可以将所有内容存储在一个表中,如果您有一个大型数据库,则按时间分区。这涉及每次数据更改时将应用程序放入新行。如果执行此操作,您可能希望创建一个仅显示当前记录的视图。实际上,我会更改表的名称并使用您当前的表名创建视图,以避免破坏任何现有代码。这将有助于您避免在针对此表转换新代码时忘记放入仅获取活动数据的限定符。

或者您可以执行两个表,其中旧值通过触发器移动(甚至不考虑通过应用程序进行移动,为此工作任何可能的表更改必须处理并且触发器是唯一确保的地方当数据发生变化时会发生这种情况。如果这样做,那么您可能希望创建一个将两个表联合在一起的视图,以便您可以查询所有数据。