在数据库中存储项目属性的组合

Posted

技术标签:

【中文标题】在数据库中存储项目属性的组合【英文标题】:Storing combinations of item properties in database 【发布时间】:2016-09-03 20:45:31 【问题描述】:

我有这样的问题:

假设我有一个物品,例如一个 CUP。我想出售它,但希望允许用户选择 CUP 属性,例如尺寸、颜色、材质。当用户选择尺寸(可能是大)、颜色(可能是黑色)和材质(可能是玻璃)时,我需要向他展示,我们在仓库中有 20 个这样的杯子,每个成本是 25 美元。现在:我不知道如何将这些组合存储在数据库中。

这是我的超级愚蠢的解决方案:

对于每个组合,我都会有一个列,但是,添加任何新组合也可能会很痛苦,因为删除一些组合,我必须以某种方式映射它们,嗯...

标识 |产品名称 |大黑玻璃价格 |大黑玻璃计数 | SmallBlackGlass价格 |小黑玻璃计数 |中...

愚蠢的想法,但至于现在没有更好的选择:/

希望很清楚我想要实现的目标。 谢谢

【问题讨论】:

为什么不创建名为属性的新表?它可以存储 cup_id 、属性和值 好的,所以你将有一个名为 product_properties 的表,然后你必须添加 product_properties_values,最后你会得到像 product_properties_values_combinations 这样的东西......但是最后一个应该是什么样子...... 关注“entity-attribute-value”标签来讨论这种模式。 【参考方案1】:

考虑以下 ERD:

系统管理员维护一个产品类别的列表,其中可能包括例如杯子。管理员还维护一个功能列表。这些可能包括 sizecolormaterial,以及他们认为对任何类型的产品可能重要的任何其他内容。然后,管理员可以创建类别和功能的交集,以指示哪些功能对特定产品类别很重要。

这为产品目录建立了“规则”。您拥有哪些类型的产品以及了解每种类型产品的重要信息。

现在,为了存储产品本身,您有 SKU 表。每个单独的产品,例如:大号黑色玻璃杯都存储在此表中。您可以在此处存储该产品的当前价格。您也可以在此处存储手头库存,尽管我建议elsewhere 不要直接存储库存数量。但是,库存管理不是您问题的基础。

对于任何特定产品 (SKU),您将拥有一个产品特性列表,其中存储了每个特定产品的特定值。重要的功能是由CATEGORY_FEATURE 表中列出的产品类别定义的功能。

在您的网站上,当客户在 PRODUCT_CATEGORY(例如 Cups)中搜索商品时,您会向他们显示适用的 CATEGORY_FEATUREs 列表。对于每个功能,您可以使用以下方法创建一个可供选择的可能值的下拉列表:

select distinct PF.value
from CATEGORY_FEATURE CF
  inner join PRODUCT_FEATURE PF
    on  CF.product_category_id = PF.product_category_id
    and CF.feature_id = PF.feature_id
where CF.product_category_id = CategoryOfInterest
  and CF.feature_id = FeatureOfInterest
order by
  PF.value

这种设计使您的管理员能够定义新的产品类别和产品功能,而无需更改数据库架构或代码。

很多人可能会指出这种设计使用了实体-属性-值 (EAV) 模式,他们同样可能会指出EAV 是邪恶的。我原则上同意在几乎所有情况下都应避免 EAV,但我也断言在某些情况下,特别是在 product catalogues 的情况下,EAV 实际上是首选设计。

【讨论】:

【参考方案2】:

Table1 => 杯赛大师

字段 => 杯号 |产品名称

示例 =>

1001 |杯A

1002 |杯乙

Table2 => 属性主文件

字段 => Property_Id |属性

示例 =>

1 |大黑玻璃

2 |小黑玻璃

3 |中黑玻璃

Table3 => 库存主数据

字段 => 杯号 |属性_Id |计数 |每件价格

示例 =>

CUP A | 1 | 3 | 45/=

CUP A | 2 | 2 | 40/=

CUP A | 3 | 2 | 35/=

CUP A | 1 | 3 | 45/=

CUP A | 2 | 2 | 40/=

注意:具有特定属性的杯子可能可用,而具有其他属性的杯子可能不可用。

【讨论】:

除了属性主表之外一切都很好。如果我将它发送到没有感觉的前端,您将如何告诉用户选择颜色和尺寸?它必须以某种方式进行硬编码、映射然后解析。【参考方案3】:

让我们尝试推理如何解决您的任务。我将描述一般概念并将其拆分为几个步骤:

    定义您要销售的产品类型:杯子、盘子、平底锅等。创建表products,字段为:id, name, price。 定义产品颜色:黑色、红色、棕色。创建表products_colours,字段为:id, name, price。 定义产品尺寸:小、中、大。创建表products_sizes,字段为:id, name, price。 在简单的情况下,所有类型的产品都将具有相同的价格,并将存储在餐桌产品中。 在简单情况下,颜色和尺寸的附加价格所有类型的产品都相同,并将存储在表格products_coloursproducts_sizes中。 创建表customers_products,字段为:id, products_id, products_colours_id, products_sizes_id, quantity。 编写一个查询以将所有表连接在一起,以从 db 中获取所有具有颜色、尺寸和所有价格的产品。 在脚本中遍历所有行并将每个产品的价格计算为产品价格、尺寸价格和颜色价格的总和

总结:这是非常基本的实施,不包括品牌、折扣等。但是,它让您了解如何扩展您的系统,以防添加影响产品最终价格的其他属性。

【讨论】:

恐怕你理解错了。系统管理员创建一个产品,然后可以完全灵活地选择可以附加到该产品的属性类型,并且价格不能与任何特定属性(如颜色)绑定,而是与产品、颜色、任何东西的组合绑定,任何事物。也就是属性表不能固定,会有!n的组合,每一个都有不同的价格和数量。除了给颜色它自己的价格之外,没有任何意义:)

以上是关于在数据库中存储项目属性的组合的主要内容,如果未能解决你的问题,请参考以下文章

MFC CComboBox 数据项如何存储?

ASP.NET Core Web API - 如何将属性组合作为原始数据存储到另一个模型的单个列中

具有远程存储但在本地查询的组合框

从预先存储的参数化访问查询填充组合框

使用工具提示 WPF 在数据网格中填充组合框

组合框不显示数据项