【问题标题】:Is this a good design for an audit table with tons of records?对于包含大量记录的审计表,这是一个好的设计吗?
【发布时间】:2010-10-17 06:37:44
【问题描述】:

我有一个表格,可以按每件商品跟踪库存数据。这是表格的简化版本(排除了一些非关键字段):

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

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

使用上面的示例,如果我想获取产品 ABC 到 2009 年 1 月 2 日的库存价值,我需要为每个唯一的产品/序列号组合选择最近的一个 记录之前到 01/03/2009,状态为“OnHand”,然后将费用相加。 (我现在还不能 100% 确定这个 select 语句会是什么样子,但我会尝试一下)。

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

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

感谢任何反馈/建议/cmets/链接。

谢谢!

【问题讨论】:

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


    【解决方案1】:

    拥有一个独立于审计数据的实时数据表将使您的生活变得更加轻松,这是一个非常好的主意。对于正常的日常操作,您甚至不需要查看审计数据,因此将其与您的实时数据放在同一个表中只会让人头疼。

    管理此问题的最简单方法是在活动表上放置一个触发器,以便每当插入/删除/更新记录时,它都会自动将新记录插入到审计表中。

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

    【讨论】:

    • 共享相同 SKU 的所有商品不一定具有相同的成本或价格。在成本方面,2002 年购买的一块 ABC 可能比今年购买的一块 ABC 便宜。售价也是如此。
    【解决方案2】:

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

    这样,您还可以轻松判断产品的哪个部分发生了变化。之前,您需要将产品的所有字段与在第一个字段之前保存的产品的所有字段进行比较。

    【讨论】:

    • 这是一个明确的可能性,尤其是对于宽表 - 虽然我不认为序列号会改变
    • 这就是前一种设计的模糊之处,它不是同一件作品,它是同一种作品 (SKU),但它有不同的序列号。
    【解决方案3】:

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

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

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

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

    或者,您还可以考虑创建一个数据集市,负责跟踪随时间的变化。 (但这需要很多时间和精力)

    【讨论】:

      【解决方案4】:

      首先,一些定义(不是临床定义,只是我自己的概念分离命名法):

      ===========

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

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

      ===========

      如果审计表的业务用途是要能够判断记录在任何时间点的样子,我会说它的构造应该与初始表相同(加上一个独特的审计-身份证)。

      如果更重要的是了解某个字段值在任何时间点(而不是整个记录)是什么,那么请尝试更缩写的 table-field-value-date 方法。请注意,使用这种方法重建整个记录需要做更多的工作,所以如果可能需要整个记录检索,请忘记它。

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

      【讨论】:

      • 除了审计表上的审计 id 之外,您还需要某种时间戳才能使其生效
      猜你喜欢
      • 1970-01-01
      • 2012-02-10
      • 1970-01-01
      • 2011-09-13
      • 1970-01-01
      • 1970-01-01
      • 2012-02-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多