我一直致力于一个项目,当我遇到一个设计困境时,我认为这是很常见的情况。请告诉我你是如何处理它的。 我们假设我们正在为商店构建Web应用程序。有一个目录表,有许多行,例如
ID |名字|价
订单表与付款方式。 我应该如何存储有关订单详情的数据,这意味着购买产品?主要关注的是如何处理目录表中的更改,如价格修改。
我想出的解决方案是:
有一个表order_details,其结构类似于目录,与orders表有多对一的关系。当用户购买某物时,必要的数据将从目录表复制到order_details表。这需要大容量存储,因为我们复制所有(或至少一些)列,并且如果在目录表中进行列修改,则需要将更改传播到order_detals。
另一个想法是利用缓慢变化的维度机制(来自数据仓库)。目录表需要其他列,例如:
ID |名字|价格|版本
|玩具车| 10 $ | 1
|泰迪熊| 2 $ | 1
|泰迪熊| 4 $ | 2
order_details表与orders表有多对一关系,与catalogs表有多对一关系。在这种情况下,order_details表中的行数相同,但列数较少。这种方法的结果是需要管理产品的版本。
答案 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
将以价格返回订单明细。
此解决方案将添加额外的连接以显示目录产品和订购的产品,但允许减少数据重复 - 价格将存储在一个位置。您将能够看到产品价格历史记录。