产品和变体 - 设计数据库的最佳方式

时间:2011-10-20 07:27:37

标签: sql database

描述

商店可以有产品(鞋子,T恤等)。每种产品可以有许多变体,每种变体可以具有不同的价格和库存,例如T恤有不同的颜色和尺寸

  • 颜色:蓝色,尺寸:L,价格:10美元,有货:5
  • 颜色:蓝色,尺码:XL,价格:10美元,有货:10
  • 颜色:白色,尺寸:L,价格:10美元,有货:6

我对这个问题的解决方案如图所示

http://dl.dropbox.com/u/43925242/erd_product_variant.png

但是这个解决方案有一些缺点

  • 很难控制同一产品的每个变体应具有相同数量的variant_features,
  • 通过变体功能搜索产品可能需要一些时间,
  • 任何其他关于我不知道......?

您可以建议为此问题简化数据库设计吗?

=====更新======

那么NoSQL解决方案呢?有什么建议吗?

3 个答案:

答案 0 :(得分:4)

基本问题是“如何存储父类的异构子类型?”。有很多选择 - 你选择的那个选项有点混合,这不一定是坏事。

我在这个主题中看到的最好的描述是在Craig Larman的书“应用UML和模式”中 - 虽然他是从面向对象而不是数据库的角度来写的。

首先要做的事情:您设置“变体”的方式可能不是您想要的 - 它表明“价格”和“股票”一起移动,而它们是非常独立的数据位。我会考虑将它们分解到自己的表中 - “variant_price”和“variant_stock”。

其次,您选择表示要素的选项通常称为“实体属性值”或EAV。它的主要好处是允许您在设计时不知道其架构的情况下存储数据,但它会使任何类型的布尔查询变得非常痛苦 - 想象一下寻找XL大小的所有红色T恤。

关系世界有三种选择(这是基于拉曼的书):

  • 每个变体的子类型。因此,您创建一个“variant_tshirt”表 尺寸,颜色等,以及尺寸,颜色,内部的“variant_trouser” 腿等。这使表保持良好和自我描述,但使 你的SQL陷入了巨大的混乱 - 它必须为每个子类型改变。

  • 包含所有可能列的单个表:在这种情况下,您有一个 包含所有子类型的所有可能字段的单个表。这条路, 你的SQL保持简单 - 但桌子变得非常混乱,而且 你依靠你的客户申请来“知道”裤子有一个 内侧腿属性,而T恤则没有。

  • 常用属性表 子类型在其自己的表中存储其唯一值。在 这个模特,假设你只有裤子和t =衬衫,你有 一个大小和颜色的“变种”表和一个“裤子”表 内腿。

每个选项都有优点和缺点 - 特别是在你事先不知道你需要哪种子类型的情况下,第一个选项是数据库端最简单,但是会造成一些混乱客户端代码。

在SQL之外,您可以使用XPath,您可以轻松地执行布尔查询或NoSQL - 但NoSQL在这里不是我的最爱,其中大多数都是基于键值关系的概念,这使得布尔值查询相当困难。

答案 1 :(得分:0)

将您的产品重命名为产品的类别和变体;从类别中删除股票(和价格,除非您的大多数变体具有相同的基本价格)。这样您就拥有了多个与同一类别相关的产品。目前,产品和变体之间存在矛盾。

您需要在应用程序级别检查的产品功能,而不是在数据库中检查。您可以将FeaturesList表(包含FeatureName,Required / Optional和CategoryID)链接到Category,以简化产品功能验证和搜索模板生成。或者,如果您的大多数类别具有相似的功能集,则可以创建与功能列表的NN关系;这样的结构有点难以维护,但更灵活。

顺便说一下,'难以控制'是非争论的。如果有严格的规则来验证数据,那么您需要遵循它们;如果没有,那么实现它们也不是你的任务。实现庞大的严格规则列表比尝试创建更容易,客户想要的两个或三个规则:)

答案 2 :(得分:0)

我建议有几张桌子,分类即T恤,牛仔裤等等,产品即T恤A,T恤B,然后是带有详细信息的变体表,例如ProductID(产品表链接),颜色,尺寸,价格,inStockQty

我还有一个只有CategoryID,ProductID的ProductsInCategories表,因此您可以将产品映射到多个类别中一次显示(想想你可能希望显示为男装T恤和女装T恤的男女通用T恤)

在类别和&之间你会有多对多的关系。使用ProductsInCategories表的产品以及Product和Variant之间的一对多关系(一个产品可以有多个变体,但变体只能属于一个产品)

您提到的缺点可以通过精心设计的存储过程和表来克服,索引也有助于提高性能。使用此表结构,控制每个变体(例如更新价格等)应该相当容易。