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