admin

用于存储历史数据的数据库结构

sql

前言:前几天,我在考虑为新应用程序使用新的数据库结构,并意识到我们需要一种有效地存储历史数据的方法。我想让其他人看一看,看看这种结构是否有任何问题。我意识到这种存储数据的方法很可能以前就已经发明了(我几乎可以肯定已经有了),但是我不知道它是否有名称,并且我尝试过的一些Google搜索都没有产生任何结果。

问题:假设您有一个订单表,并且订单与下订单的客户的客户表相关。在正常的数据库结构中,您可能会期望如下所示:

orders
------
orderID
customerID


customers
---------
customerID
address
address2
city
state
zip

非常简单明了,orderID具有customerID的外键,这是customer表的主键。但是,如果要在订单表上运行报表,我们将把客户表加入到订单表中,这将带回该客户ID的当前记录。如果下订单时客户的地址不同并且后来又更改了该怎么办。现在,我们的订单不再反映下订单时该客户地址的历史记录。基本上,通过更改客户记录,我们只更改了该客户的所有历史记录。

现在有几种解决方法,其中一种是在创建订单时复制记录。不过,我想出的是,我认为这是一种更简单的方法,可能更优雅一些,并且具有在进行任何更改时进行日志记录的额外好处。

如果我改成这样的结构怎么办:

orders
------
orderID
customerID
customerHistoryID


customers
---------
customerID
customerHistoryID


customerHistory
--------
customerHistoryID
customerID
address
address2
city
state
zip
updatedBy
updatedOn

请原谅格式,但我认为您可以看到这个想法。基本上,这种想法是,只要更改,插入或更新客户,就可以增加customerHistoryID并使用最新的customerHistoryID更新客户表。现在,订单表不仅指向customerID(允许您查看客户记录的所有修订版),而且还指向customerHistoryID,后者指向记录的特定修订版。现在,订单反映了创建订单时的数据状态。

通过向customerHistory表中添加一个updateby和updatedon列,您还可以看到数据的“审核日志”,因此您可以看到谁进行了更改以及何时进行了更改。

删除可能是一个潜在的弊端,但是我对此并不真正担心,因为什么也不能删除。但即使如此,根据数据域的不同,使用activeFlag或类似的方法也可以实现相同的效果。

我的想法是所有表都将使用此结构。每当检索历史数据时,都将使用customerHistoryID将其与历史表结合起来,以显示该特定订单的数据状态。

检索客户列表很容易,只需在customerHistoryID上联接到客户表即可。

无论是从设计角度还是出于性能原因,任何人都可以看到这种方法的任何问题。请记住,无论我做什么,我都需要确保保留历史数据,以便以后对记录的更新不会更改历史记录。有没有更好的办法?这是一个有名称或任何文件的已知想法吗?

谢谢你的帮助。

更新:
这是我真正要拥有的非常简单的示例。我的实际应用程序将具有“订单”,并带有指向其他表的多个外键。始发地/目的地位置信息,客户信息,设施信息,用户信息等。曾有几次建议我可以将该信息复制到订单记录中,而且我已经看到过很多次,但这会导致记录包含数百列,在这种情况下,这实际上是不可行的。


阅读 260

收藏
2021-05-10

共1个答案

admin

当我遇到这样的问题时,一种选择是对历史记录表进行排序。它的功能相同,但易于操作

orders
------
orderID
customerID
address
City
state
zip



customers
---------
customerID
address
City
state
zip

编辑:如果您喜欢的列数很高,则可以按自己的喜好将其分开。

如果您确实选择了另一个选项并使用了历史表,则应考虑使用时空数据,因为您可能不得不处理需要更正历史数据的可能性。例如,客户将其当前地址从A更改为B,但您还必须更正当前正在履行的现有订单上的地址。

另外,如果您使用的是MS SQL
Server,则可能要考虑使用索引视图。这将使您可以将较小的增量插入/更新性能降低与较大的选择性能提高进行交易。如果您不使用MS SQL
Server,则可以使用触发器和表来复制它。

2021-05-10