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



我一直在做一个项目,当我遇到一个设计难题时,我认为这是非常常见的情况。请告诉我你是怎么处理的。让我们假设我们正在为一家商店构建一个网络应用程序。有一个目录表,有许多行,例如

ID |名称|价格

  1. |玩具车|10$
  2. |泰迪熊|2$

以及带有付款方式的订单表。我应该如何存储有关订单详细信息的数据,即购买的产品?主要关注的是如何处理目录表中的更改,如价格修改。

我想出的解决方案是:

  1. 有一个结构类似于catalog的表order_details,并且与orders表有多对一关系。当用户购买某物时,必要的数据会从目录表复制到order_details表。这需要大的存储空间,因为我们复制所有(或至少部分)列,并且在catalogs表中修改列的情况下,需要将更改传播到order_detals。

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

ID|名称|价格|版本

  1. |玩具车|10$|1

  2. |泰迪熊|2$|1

  3. |泰迪熊|4$|2

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

这里有一个类似问题的答案,它讨论的是Version Normal Form.

您需要将价格(以及您想要跟踪的任何其他数据)标准化到一个单独的表中。您的FK将继续正常工作。你所要做的就是得到订单发出时有效的价格。这有点棘手,但并不难。

通常,数据库设计取决于商店应用程序逻辑。但我猜这种方法会对你有所帮助:

在中创建表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

将返回订单详细信息和价格。

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

最新更新