更改参考数据并维护历史记录"

时间:2017-01-19 13:51:48

标签: database design-patterns database-design

我一直致力于一个项目,当我遇到一个设计困境时,我认为这是很常见的情况。请告诉我你是如何处理它的。 我们假设我们正在为商店构建Web应用程序。有一个目录表,有许多行,例如

ID |名字|价

  1. |玩具车| 10 $
  2. |泰迪熊| 2 $
  3. 订单表与付款方式。 我应该如何存储有关订单详情的数据,这意味着购买产品?主要关注的是如何处理目录表中的更改,如价格修改。

    我想出的解决方案是:

    1. 有一个表order_details,其结构类似于目录,与orders表有多对一的关系。当用户购买某物时,必要的数据将从目录表复制到order_details表。这需要大容量存储,因为我们复制所有(或至少一些)列,并且如果在目录表中进行列修改,则需要将更改传播到order_detals。

    2. 另一个想法是利用缓慢变化的维度机制(来自数据仓库)。目录表需要其他列,例如:

    3. ID |名字|价格|版本

      1. |玩具车| 10 $ | 1

      2. |泰迪熊| 2 $ | 1

      3. |泰迪熊| 4 $ | 2

      4. order_details表与orders表有多对一关系,与catalogs表有多对一关系。在这种情况下,order_details表中的行数相同,但列数较少。这种方法的结果是需要管理产品的版本。

2 个答案:

答案 0 :(得分:2)

对类似问题的回答是here,其中讨论了版本范式。

您需要将价格(以及您要跟踪的任何其他数据)规范化为单独的表格。您的FK将继续正常工作。您所要做的就是获得订单生效时的价格。这有点棘手但并不困难。

答案 1 :(得分:1)

通常,您的数据库设计取决于您的商店应用程序逻辑。但我猜这种方法可以帮助你:

创建一个表catalog_prices (priceId, productId, price, date)并在其中 目录表将price列更改为priceId。所以, 每个产品都有一个当前价格,表catalog_prices将有产品价格历史记录。所以,查询

SELECT c.ID, c.name, p.price FROM catalogs AS c 
INNER JOIN catalog_prices AS p ON c.priceId = p.priceId

将返回所有价格和查询的产品

SELECT c.ID, c.name, p.price, p.date FROM catalogs AS c 
INNER JOIN catalog_prices AS p ON c.ID = p.productId 

将返回所有价格历史记录。

order_details表格中添加productPriceId列。所以查询

SELECT d.ID, d.orderId, c.name, p.price FROM order_details AS d 
INNER JOIN catalog_prices AS p ON p.priceId = d.productPriceId
INNER JOIN catalogs AS c ON p.productId = c.ID

将以价格返回订单明细。

此解决方案将添加额外的连接以显示目录产品和订购的产品,但允许减少数据重复 - 价格将存储在一个位置。您将能够看到产品价格历史记录。