【问题标题】:Duplication of data in a database versus application design数据库中的数据重复与应用程序设计
【发布时间】:2014-02-18 15:40:47
【问题描述】:

我有一个关于在某些情况下处理数据集的应用程序设计问题。

假设我有一个使用一些实体的应用程序。我们有一个订单,其中包含有关客户、截止日期等的信息。然后我们有一个与订单有一对多关系的服务实体。服务包含它的名称。除此之外,我们还有一个 Rule 实体,它设置了一些关于从材料库存中扣除什么的规则。它与Service实体是一对多的关系。

现在,我的问题是:如何处理这种情况,当我创建订单并将其保存到数据库中时,与它的关系,但同时,我不希望对发生的实体进行更改与生成的订单可见。我需要将订单和与之关联的数据视为某种日志,以便从表中删除服务或更改一组规则,不会更改已生成的订单、服务和期间使用的规则过程。

通常,我将如何处理该问题,将复制服务和规则,并将其插入新表中,以便数据独立于在订单生成期间使用的数据。 Order 只会指向重复的数据,而不是原始数据,这可以解决我的问题。但这是数据重复,而且我认为这不是最好的方法。

那么,如果你理解了我的问题,你知道解决这类问题的更好主意吗?如果我写的没有任何意义,我很抱歉。告诉我,我会努力用更好的方式表达自己。

【问题讨论】:

  • 听起来您的订单需要在下订单时其他地方的字段值的快照。您的服务和规则表可以包含修订号列,以便订单引用修订以及数据,当您的 UI 认为它正在更改规则或服务时,它实际上是在添加具有更高修订号的新记录?
  • 这是处理问题的一种非常有趣的方式。唯一的缺点是,您必须从不再引用的实体中清理数据库。
  • 或者,如果这些更改是手动的,您可以无限期地保留它们,并且它们会成为您的配置管理的一部分(带有额外的列来跟踪谁、何时以及为什么)
  • 我认为您必须复制信息。商店中显示的价格标签是动态的,但发票上显示的价格不会改变。您不需要复制所有内容,只需复制需要的内容即可。另一种选择是保留所有历史更改并存储 AsOf 日期“此订单使用 AsOf 此日期的信息”。
  • 好吧,一切都取决于我想要多大的灵活性。谢谢两位的回答。你提出了一些非常有趣的建议。

标签: database database-design application-design


【解决方案1】:

我最近一直在调查同样的案例,所以我想分享一些想法。

这个想法是将需要版本控制的每个实体视为一个对象并存储在数据库对象的实例中。比如说,对于service 实体,可以这样表示:

  1. service 表,只包含service_id 列,PrimaryKey;
  2. service_state(或..._instance)表,其中包含:
    • service_idservice.service_id 的外键;
    • state_start_dt,此状态变为活动状态的时刻,NOT NULL
    • state_end_dt,这个状态被废弃的时刻,NULLable;
    • service 的所有真实属性;
    • 主键是service_id + state_start_dt
  3. 当然,state_start_dt::state_end_dt 范围不能重叠,应该受到限制。

这种方法有什么好处?

  1. 您拥有基本对象状态转换的完整历史记录;
  2. 您可以在给定的时间点查询系统;
  3. 可以通过插入带有所需state_start_dt 标记的适当记录提前完成新配置的交付;
  4. 变更审计已集成到设计中(嗯,完整的跟踪需要几个额外的列)。

怎么了?

  1. 会有数据重复。为了减少它,请确保拆分实例化关系。比如:不要为客户数据创建一个表,而是为凭据、地址、联系人、财务信息等创建一堆表。
  2. 真正的主键是service.service_id,而信息保存在从属表service_state中。这可能会导致以下情况:您的 service 存在,而有人(有意或无意地)删除了所有 service_state 记录。
  3. 很难确定在哪个时间点将state 记录删除到离线存档中是安全的,因为只要系统中存在引用service 的实体,就应该在之前检查它们的生效日期删除任何 state 记录。
  4. 由于#3,不能只从service_state 中删除记录。事实上,依赖state_end_dt 列也是错误的,因为服务可能已经激活了一段时间然后被抑制了。并且在服务处于活动状态时查询服务应指示服务处于活动状态。因此,status 列是必需的。

我认为,记住这种方法的缺点,它非常好。 虽然我想从关系模型的角度听听一些 cmets - 特别是关于这种设计的缺点。

【讨论】:

  • 我不会说它使问题复杂化了,但这绝对是一个复杂的解决方案,在实际实施之前需要一些思考。如果我们需要使用更改的故事情节,这将很有用。这里适合这种情况。虽然我经常遇到的一个事实是,除了数据重复之外,我还得在 Order 的生成过程之后添加一个额外的信息字段。在这里,我们可以使用与 service_state 一对一关系的附加表来解决这个问题。对于常规数据重复,我只是将订单数据放入第二个表中。
【解决方案2】:

我建议将数据复制到单独的快照表中。您当然可以在主表上使用版本控制方案,但我会质疑减少重复数据的努力会增加多少额外的复杂性。我发现数据模型中的额外复杂性导致系统更难扩展。我认为重复数据在这里是两害相权取其轻。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-21
    • 2011-12-07
    • 1970-01-01
    • 1970-01-01
    • 2018-01-31
    • 2015-11-03
    • 2014-03-07
    • 1970-01-01
    相关资源
    最近更新 更多