这是一个有大量记录的审计表的好设计吗?

时间:2009-04-03 02:35:49

标签: database-design query-optimization audit-tables

我有一张表格可以跟踪每件作品的库存数据。这是表格的简化版本(不包括一些非关键字段):

UniqueID,
ProductSKU, 
SerialNumber,
OnHandStatus,
Cost,
DateTimeStamp

每当某件事发生某事时,都会创建一个新的审计记录。例如,我的产品ABC第一次被添加到库存中时,我得到了这样的记录:

1, ABC, 555, OnHand, $500, 01/01/2009 @ 02:05:22

如果ABC序列号555的成本发生变化,我会得到一条新记录:

2, ABC, 555, OnHand, $600, 01/02/2009 @ 04:25:11

如果这件作品被出售,我还会得到另一张唱片:

3, ABC, 555, Sold, $600, 02/01/2009 @ 5:55:55

如果引入新的ABC,我会得到这条记录:

4, ABC, 888, OnHand, $600, 02/05/2009 @ 9:01:01

我需要能够尽快在任何时间点获取给定产品的现有库存值。

使用上面的示例,如果我想从01/02/2009获取产品ABC的库存值,我需要为每个唯一的产品/序列号组合选择最近的单个< / strong>记录之前至01/03/2009,状态为“OnHand”,然后将费用加起来。 (我不是100%肯定这个选择陈述在这一点上会是什么样子,但我会稍微试验一下。)

我的问题:对于我所描述的审计表类型,这是一个很好的结构吗?也就是说,如果索引适当,它是否适合快速查询? (我试图想象当这个表增长到数百万行时会发生什么。)

我是否应该将历史记录分解为单独的表,并且只在“活动”表中保留每个ProductID / SerialNumber组合的最新记录?

欢迎任何反馈/建议/意见/链接。

谢谢!

4 个答案:

答案 0 :(得分:3)

使用与审计数据分开的实时数据表可以让您的生活更轻松,这是一个非常好的主意。对于正常的日常操作,您甚至不需要查看审计数据,因此将其与实时数据放在同一个表中会导致令人头疼。

管理此方法的最简单方法是在活动表上设置触发器,这样无论何时插入/删除/更新记录,它都会自动将新记录插入审计表中。

编辑: 扩展Kevin's对此的想法,我想无论序列号如何,共享相同SKU的所有部分都会有相同的价钱?如果是这种情况,拥有单独的价格表也绝对是一个好主意。

答案 1 :(得分:1)

并非所有值都会立即更新,为什么要重现所有静态信息?我认为您应该有序列号,状态和成本的不同表格。每个表格还将包含产品ID和更新日期。

通过这种方式,您还可以轻松判断产品的哪个部分已更改。之前,您可以将产品的所有字段与第一个产品的所有字段进行比较。

答案 2 :(得分:0)

您需要将审核数据分开。随着时间的推移,将当前数据与审计数据保持在一起会影响性能。

最简单的实现是创建一个与生产相同的模式的单独数据库。为审计数据库中的每个表添加日期时间戳。从生产主键和新的日期时间戳创建复合主键。

在生产数据库上设置触发器,以便生产数据库中的每个插入/更新都会触发插入审计数据库的插入。插入审计数据库的值将是新插入的值。

仅将审计数据库用于审计报告目的。

或者,您还可以查看创建数据集市,该数据集市将负责跟踪一段时间内的变化。 (但这需要花费大量的时间和精力)

答案 3 :(得分:0)

首先,一点定义(不是临床定义,只是我自己的思想分离命名法):

==========

初始表:您添加和检索的日常表。

审计表:在其相关的初始表中包含任何记录的多个版本的表。

==========

如果审计表的业务用途是能够在任何时间点告诉记录的样子,我会说它应该与初始表格相同(加上一个独特的审计 - ID)。

如果更重要的是知道任何时间点的字段值(与整个记录相对)是什么,那么尝试更简化的table-field-value-date方法。请注意,使用这种方法重建整个记录需要做更多的工作,所以如果有必要进行全记录检索,请忘记它。

总的来说,我认为在大多数情况下,使用最新版本的记录的快速性能比使用审计数据的性能更重要。因此,我建议创建与初始表相同的审计表(加上自动编号的代理键),并在添加到初始表时触发将相同数据插入到审计表中。这使得记录的数量在初始表中保持相对静态,并且性能不会随着时间的推移而降低。