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

3

描述

商店可以拥有产品(鞋子、T恤等)。每个产品可以有许多变体,其中每个变体的价格和库存都可能不同,例如T恤有不同的颜色和尺码。

  • 颜色:蓝色,尺码:L,价格:$10,库存:5
  • 颜色:蓝色,尺码:XL,价格:$10,库存:10
  • 颜色:白色,尺码:L,价格:$10,库存:6

我提出的解决方案如下图所示:

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

但这种解决方案有一些缺点:

  • 很难控制同一产品的每个变体应该具有相同数量的变体功能,
  • 通过变体功能搜索产品可能需要一些时间,
  • 其他问题我不清楚......?

您能否建议简化此问题数据库设计的方法?

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

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


6
图片链接已失效,您是否介意重新上传图片? - Flux
问题有点无效,因为图片链接已损坏。 - Ahmed Eid
3个回答

5
基本问题是“如何存储父类的异构子类型?”有许多选择 - 你选择的是一种混合方式,这并不一定是坏事。
我见过的最好的描述此主题的书是Craig Larman的《应用UML和模式》- 尽管他从面向对象而非数据库的角度写作。
首先:您设置“变体”的方式可能不是您想要的 - 它表明“价格”和“库存”一起移动,而它们是非常独立的数据。我会考虑将它们分解成它们自己的表 - “variant_price”和“variant_stock”。
其次,您选择的表示特征的选项通常称为“实体属性值”或EAV。它具有允许您在设计时存储数据而不知道其架构的重大优点,但是使任何类型的布尔查询都变得非常麻烦 - 想象一下查找所有红色XL尺码T恤衫。
在关系世界中有3种替代方案(基于Larman书):
1. 每个变量的子类型。因此,您创建了一个“variant_tshirt”表,其中包括大小、颜色等,以及一个“variant_trouser”,其中包括大小、颜色、内腿等。这使得表格保持良好的自我描述性,但使SQL变得非常混乱 - 它必须为每个子类型更改。 2. 包含所有可能列的单个表:在这种情况下,您有一个包含所有子类型的所有可能字段的单个表。这样,您的SQL保持简单 - 但是表格变得非常混乱,并且您依赖于客户端应用程序“知道”长裤具有内腿属性,而T恤衫则没有。 3. 具有共同属性的表,子类型将其唯一值存储在自己的表中。在此模型中,假设您只有长裤和T恤衫,则具有大小和颜色的“变体”表,以及具有内腿的“长裤”表。
每个选项都有优缺点 - 特别是在您不知道需要哪些子类型的情况下,第一种选项在数据库端最简单,但会为客户端代码创建一些混乱。
在SQL之外,您可以选择XML - 使用XPath,您可以轻松执行布尔查询,或者NoSQL - 但NoSQL不是我在这里最喜欢的,它们大多基于键值关系的概念,使布尔查询变得相当困难。

1
一个问题是这三个选择都不知道将存储哪种产品在数据库中。 - Przemek

0

将您的产品名称更改为类别,将变体更名为产品;从类别中删除库存(和价格,除非大多数变体都具有相同的基础价格)。这样,您就可以拥有多个与同一类别相关联的产品。目前,产品和变体之间存在歧义。

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

顺便说一句,“难以控制”并不是一个论据。如果有严格的规则来验证数据,那么您需要遵循它们;如果没有,则不是您的任务来实现它们。实施大量严格的规则比试图发明两三个规则客户可能想要要容易得多 :)


0
我建议使用几个表,包括类别(如T恤、牛仔裤等)、产品(如T恤A、T恤B)和变体表,其中包含ProductID(链接到产品表)、颜色、尺码、价格和库存数量的详细信息。
我还会有一个ProductsInCategories表,只包含CategoryID、ProductID,这样您就可以将一个产品映射到多个类别中(例如Unisex T恤,您可能希望同时显示为男士T恤和女士T恤)。
通过ProductsInCategories表,类别和产品之间可以建立多对多关系,而产品和变体之间可以建立一对多关系(一个产品可以有多个变体,但一个变体只能属于一个产品)。
您提到的缺点可以通过良好设计的存储过程和表来克服,索引也将有助于性能。此外,控制每个变体(如更新价格等)应该相当容易,采用这种表结构。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接