【问题标题】:Relational Databases: Current Data vs. Historical Data, best Practice关系数据库:当前数据与历史数据,最佳实践
【发布时间】:2018-04-21 03:16:32
【问题描述】:

让我们以关系数据库为例,例如MySQL。为简单起见,我将专注于重要的事情:拥有一个包含订单的表,其中包含 order_id(主键)order_date 之类的字段和一个外键 fk_supplier,它引用表中的主键 supplier .该表还有一个名为supplier_name 的字段。 现在,让我们想象一下,有一个 php-website 显示了在表格中进行的所有订单。表的每一行都由order_idorder_date 和supplier_name 组成(sql 语句连接了两个表)。 到目前为止一切都很好。现在,有人更改了其中一个订单中引用的一个供应商的名称:历史数据变为不真实或虚假。 我的问题是:防止这种情况的最佳做法是什么?我想到了三个解决方案:

  1. 不要让用户更改订单中引用的供应商数据行。如果名称发生变化,让他添加新的供应商。
  2. 始终将当前供应商数据(例如供应商名称)与订单记录一起保存,不要使用主键/外键引用。
  3. 引入时间片:每次,供应商的一个重要属性(如名称)发生变化,创建一个新的时间片。不仅参考订单中的supplier_id,还参考对应的时间片。

所有这些方法都有优点和缺点。例如,第 2 点似乎很脏,并且违反了关系数据库的所有规则。在我看来,第 3 点通常是要走的路。但是需要很多努力,编程明智。用户体验/可用性也变得非常糟糕。

我想听听经验丰富的开发人员和数据库设计人员如何处理这个问题。

【问题讨论】:

  • 我将作为选项 2 实施,但我看不到(从您的描述)为什么您需要以旧订单存储过时的(以前的)供应商名称? IMO 供应商表应该有 SupplierID INT 这是主键和名称是无关紧要的。
  • 我会考虑选项 3 的变体,您只需创建一个新的供应商并添加一个额外的列来存储 OriginalSupplierID,而不是时间片,以便能够跟踪关系。可能有更好的解决方案,但需要更多背景信息。
  • 在这种情况下,我的选择是 2 但您仍然将 PK 和 FK 保留到供应商记录,同时将供应商详细信息的快照保存在另一个表中,例如OrderInvoiceDetails。
  • 至于"Point 2 e.g., seems pretty dirty and against all rules of a relational database":不,不是。您存储完整的订单,以便重新打印。它独立于当前的供应商名称和地址,因此您将数据与订单一起存储。这是一个有效的选项,不违反数据库规范化。
  • @whocares81:我的意思是:这不是多余的。您存储带有名称和地址的订单。同一供应商的另一个订单可以有另一个名称和地址。同时,供应商可以拥有另一个名称和地址。这有什么多余的?这是存储数据的正确方法。顺便说一下,订单中的商品价格也是如此。但是,正如您已经展示的那样,还有其他选择。我要说的是:这不违反规范化并且是一个有效的选择。

标签: mysql sql-server database relational


【解决方案1】:

选项 3 的一种形式,其中您有关于供应商信息的 StartDate 和 EndDate。这样,数据在所有时间都是准确的(供应商名称在给定时间是正确的)。您还可以做的一件事是创建一个电子表格,其内容每晚都会加载到包含供应商信息的数据库中(进入 fact_Supplier 表或查找表)。对供应商的所有编辑都通过此电子表格进行,只有那些将负责此类事情的选定人员才能访问。如果电子表格中有更改,则供应商表中的先前信息将结束日期,并插入带有新信息的新记录。任何更改都会发生这种情况,供应商名称、供应商地址等。

【讨论】:

    【解决方案2】:

    将扩展我的评论:

    我会选择选项 2,但有一些修改:

    • 供应商表应保持原样。
    • 订单表应继续引用供应商表
    • 创建新表,例如OrderInvoiceDetails 应与 Order 表具有 1 对 1 的关系,与供应商具有 FK。此表将包含供应商详细信息的快照。

    优点:

    • 简单高效的查询
    • 如果需要,可以从供应商表中单独修改发票详细信息。
    • 我认为从逻辑上讲这是最佳解决方案,因为您希望存储与特定订单相关的供应商详细信息,而不是存储供应商历史数据。
    • 旧数据可以与订单数据一起轻松存档

    缺点:

    • 存储冗余数据,尤其是对于详细信息不经常更改的供应商

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-15
      • 1970-01-01
      • 2013-06-30
      • 2014-08-01
      相关资源
      最近更新 更多