前言: 最近我在想一个新应用的数据库结构,意识到我们需要一种有效的方法来存储历史数据。我想让其他人看看这个结构是否有任何问题。我认识到这种存储数据的方法很可能已经被发明了(我几乎肯定是这样),但我不知道它有没有一个名称,我尝试了一些谷歌搜索,但没有找到任何东西。
问题: 假设您有一个订单表,并且订单与放置订单的客户表相关联。在正常的数据库结构中,您可能会期望像这样:
orders
------
orderID
customerID
customers
---------
customerID
address
address2
city
state
zip
相当直接,orderID具有customerID的外键,该外键是客户表的主键。但是,如果我们运行订单表上的报告,我们将连接客户表和订单表,这将带回该客户ID的当前记录。如果在下订单时客户地址不同并且后来已更改怎么办?现在我们的订单不再反映下订单时该客户的历史地址。基本上,通过更改客户记录,我们刚刚更改了该客户的所有历史记录。现在有几种方法可以解决这个问题,其中之一是在创建订单时复制记录。然而,我想出了一种更容易做到并且更加简洁的方法,还有一个额外的好处,就是每次更改都会进行日志记录。
那如果我像这样构建结构呢:
orders
------
orderID
customerID
customerHistoryID
customers
---------
customerID
customerHistoryID
customerHistory
--------
customerHistoryID
customerID
address
address2
city
state
zip
updatedBy
updatedOn
请原谅格式问题,但我认为您可以理解这个想法。基本上,每当更改客户时(插入或更新),就会递增customerHistoryID,并使用最新的customerHistoryID更新customers表。现在,order表不仅指向customerID(允许您查看客户记录的所有修订版本),还指向customerHistoryID,该ID指向记录的特定修订版本。现在,订单反映了创建订单时数据的状态。通过向customerHistory表添加updatedby和updatedon列,您还可以查看数据的“审计日志”,因此您可以查看谁何时进行了更改。
一个潜在的缺点可能是删除操作,但出于这种需求,我并不真的担心这一点,因为永远不应该删除任何内容。但是即使如此,根据数据域,也可以使用activeFlag或类似的东西来实现相同的效果。
我的想法是所有表都将使用这种结构。每当检索历史数据时,它将使用customerHistoryID与history表连接,以显示该特定订单的数据状态。
检索客户列表很容易,只需要在customer table中使用customerHistoryID连接即可。
有人能否看到这种方法存在任何问题,无论是从设计角度,还是从性能方面考虑,这是否不好。请记住,无论我做什么,都必须确保历史数据得以保留,以便对记录进行的后续更新不会更改历史记录。是否有更好的方法?这是一种已知的想法吗?或者有关于它的任何文档?
感谢您的任何帮助。
更新: 这是我真正拥有的非常简单的示例。我的实际应用程序将具有与其他表的几个外键相关联的“订单”。起始/目标位置信息、客户信息、设施信息、用户信息等。有几次建议我可以在那时将信息复制到订单记录中,并且我已经看到过很多这样做的情况,但是这将导致具有数百列的记录,在这种情况下确实行不通。