Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 数据库审计跟踪并重建以前的结果_Sql_Database_Database Design - Fatal编程技术网

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

Sql 数据库审计跟踪并重建以前的结果,sql,database,database-design,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

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

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

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 int)

和另一个存储所有历史更改的表

CompanyID CompanyName Description Address Industry ChangeTime Action User
大多数查询都是从今天开始获取联系人列表,这在新模式下很容易,但我仍然希望能够执行诸如“从20130416开始获取联系人列表”之类的查询,该查询应返回1行。通过当前条目和更改日志来构建历史数据感觉相当肮脏

在类似情况下你会怎么做?原因是什么


最棒的是,

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

这些表还有一个“修改的”日期字段。因此,如果用户进行了更新,您只需将当前时间段0记录更新为-1,并插入一个包含修改数据的新行。这样你就可以知道谁改变了什么,什么时候改变了什么。或者,在数据每天更新的情况下,修改日期将是加载记录的日期


希望这能有所帮助。

审计跟踪通常会确定谁改变了什么。你在寻找完全不同的东西。您希望您的数据库回答以下问题:
select*from table_name where(数据显示与2013-01-15相同)

据我所知,Richard Snodgrass发表了关于使用SQL解决此类问题的最早综合性著作。他将面向时间的数据库(和表)分为以下几类

  • 有效的时间表:这些记录了“不断变化的现实的历史”
  • 事务时间表:它们捕获“变化表的状态序列”
  • 双时态表:它们实现了有效的时间表和事务时间表
我想你在找双时表


他的书可以从亚利桑那大学的教授网页下载到PDF下载。既然它是免费的,在你把自己挖到洞里之前,没有理由不把它略过。仔细阅读代码以了解完整性约束。(如果这些都弄错了,你的数据库几乎一文不值。)

我认为你的思路是对的,约翰尼。我的建议是像你建议的那样拆分表

特拉维斯的解决方案可能是可行的,但是考虑到历史快照会随着时间的推移而变得非常大。如果将它们分开,则当天的查询将运行得很快。如果将它们放在一起,随着时间的推移,查询自然会越来越慢(当然可能需要一段时间才能注意到)

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

例如:

公司表:

公司ID、公司名称、描述、地址、行业

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

快照ID、公司ID、公司名称、描述、地址、行业

快照表:

SnapshotID、CreateDate、CreateDateTime


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

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

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

或者您可以做两个表,其中旧值通过触发器移动(甚至不考虑通过应用程序进行移动,以便在数据更改时必须处理任何可能的表更改,而触发器是确保这一点发生的唯一地方)。如果这样做,则可能需要创建一个将两个表合并在一起的视图,以便

CompanyID CompanyName Description Address Industry ChangeTime Action User
CompanyID, CompanyName, Description, Address, Industry
SnapshotID, CompanyID, CompanyName, Description, Address, Industry
SnapshotID, CreateDate, CreateDateTime