前言:前几天,我在考虑为新应用程序使用新的数据库结构,并意识到我们需要一种有效地存储历史数据的方法。我想让其他人看一看,看看这种结构是否有任何问题。我意识到这种存储数据的方法很可能以前就已经发明了(我几乎可以肯定已经有了),但是我不知道它是否有名称,并且我尝试过的一些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上联接到客户表即可。
无论是从设计角度还是出于性能原因,任何人都可以看到这种方法的任何问题。请记住,无论我做什么,我都需要确保保留历史数据,以便以后对记录的更新不会更改历史记录。有没有更好的办法?这是一个有名称或任何文件的已知想法吗?
谢谢你的帮助。
更新: 这是我真正要拥有的非常简单的示例。我的实际应用程序将具有“订单”,并带有指向其他表的多个外键。始发地/目的地位置信息,客户信息,设施信息,用户信息等。曾有几次建议我可以将该信息复制到订单记录中,而且我已经看到过很多次,但这会导致记录包含数百列,在这种情况下,这实际上是不可行的。
当我遇到这样的问题时,一种选择是对历史记录表进行排序。它的功能相同,但易于操作
orders ------ orderID customerID address City state zip customers --------- customerID address City state zip
编辑:如果您喜欢的列数很高,则可以按自己的喜好将其分开。
如果您确实选择了另一个选项并使用了历史表,则应考虑使用时空数据,因为您可能不得不处理需要更正历史数据的可能性。例如,客户将其当前地址从A更改为B,但您还必须更正当前正在履行的现有订单上的地址。
另外,如果您使用的是MS SQL Server,则可能要考虑使用索引视图。这将使您可以将较小的增量插入/更新性能降低与较大的选择性能提高进行交易。如果您不使用MS SQL Server,则可以使用触发器和表来复制它。