关系数据库:当前数据与历史数据,最佳实践

时间:2017-11-08 12:21:50

标签: mysql sql-server database relational

让我们来一个关系数据库,例如MySQL的。为了简单起见,我将专注于重要的事情:拥有一个包含订单的表,其中包含 function cropper_now(){ var $previews = $('.preview'); var cropBoxData; var canvasData; $('#image').cropper({ aspectRatio : 1 / 1, viewMode: 1, minCropBoxHeight : 200, minContainerHeight : 200, zoomOnWheel : false, zoomable: false, built: function () { $('#image').cropper('setCanvasData', canvasData); $('#image').cropper('setCropBoxData', cropBoxData); console.log( $('#image').cropper("getData")); }, crop: function (e) { var json = [ '{"x":' + e.x, '"y":' + e.y, '"height":' + e.height, '"width":' + e.width, '"rotate":' + e.rotate + '}' ].join(); $('input[name="imagecropperdata"]').val(json); } }); (主键)order_id和外键fk_supplier等字段,它们引用了一个主键。表格1}}。该表还有一个名为order_date的字段。 现在,让我们想象一下,有一个php网站显示了在表格中生成的所有订单。该表的每一行都包含suppliersupplier_name和supplier_name(sql语句在两个表上建立了连接)。 到目前为止一切都还好。现在,有人更改了其中一个订单中引用的一个供应商的名称:历史数据变得不真实或错误。 我的问题是:为了防止这种情况,最佳做法是什么?我想到了三个解决方案:

  1. 不要让用户更改订单中引用的供应商数据行。如果名称发生变化,请让他添加新的供应商。
  2. 始终使用订单记录保存当前供应商数据(例如供应商名称),并且不要使用主键/外键引用。
  3. 介绍时间片:每次更改供应商的重要属性(如名称),创建新的时间片。不仅可以参考订单中的supplier_id,还可以参考相应的时间片。
  4. 所有这些方法都有优点和缺点。例如,点2似乎非常脏,并且违反了关系数据库的所有规则。在我看来,第3点通常是要走的路。但需要付出很多努力,编程明智。用户体验/可用性也非常糟糕。

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

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

将扩展我的评论:

我会选择选项2,但稍作修改:

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

优点:

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

缺点:

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