【问题标题】:How to design a db for sales that incorporates attributes into products in an inventory?如何设计一个销售数据库,将属性整合到库存中的产品中?
【发布时间】:2019-04-06 20:51:11
【问题描述】:

我正在尝试设计一个包含产品、产品类型、产品属性的数据库,该数据库还存储成本和库存(库存)。我希望这具有尽可能少的 const/硬编码,并且在未来也可以扩展。

我遇到的问题是我希望将多个属性绑定到一个产品,其中一些属性会导致产品成本增加,并保持具有所有这些属性的产品库存。

这是我当前的数据库图:

我曾考虑将“ProductAttributeID”列附加到 ProductPricing 和 Product Stock/Supply 表中。

这适用于单个属性,但如果要考虑两个属性则不行。

即:

Product = Shirt
Attribute = Size (small, medium, large)
Attribute#2 = Color (red, green, blue)
...

我想我可以创建一个 ProductAttributeModifier 表,以将一个值加/减/除/乘以总值。

ProductAttributeModifier
========================
ProductAttributeID (bigint) FK_,
Operator (char(1)), //+, -, *, /, %
CostValue decimal(7,2)

这样我可以对具有多个属性的产品的总价值进行汇总汇总。

这种方法有什么缺陷吗?

我将如何处理 ProductSupply?我曾考虑将多个列作为外键约束添加到不同的 ProductAttributes,但这是不可扩展的,并且需要将来了解该产品。

也许另一张桌子可以作为一个单独数量的连接点?迭代所有属性?这种方法也有陷阱吗?

ProductAttributeSupply
======================
ProductSupplyId (bigint) FK_,
AttributeID (bigint) FK_,
Quantity (int/bigint)

将整体供应总量放在视图/存储过程中是否更有意义?

我希望图表能够处理以下场景:

  1. 产品没有、单个或多个属性
  2. 为属性修改成本做好准备(中到大)
  3. 成本修饰符是可选的
  4. 计算我们库存中所有属性匹配的适当产品数量
  5. 当我们在数据库中收到时,正确保存与每个属性匹配的产品数量。 '产品库存'

【问题讨论】:

标签: sql diagram


【解决方案1】:

您的 ProductAttributeModifier 方法可能有效,但我不明白您为什么需要更改有关供应的任何内容。

Products:
   - 1: small green shirt
   - 2: large green shirt

Attributes:
  - 1: size
  - 2: color

ProductAttributes (ProductId, AttributeId):
  - (1, 1) small
  - (1, 2) green
  - (2, 1) large
  - (2, 2) green

您的库存/供应不需要属性,您只需要小绿衬衫和大绿衬衫的数量,对吧?

如果您希望属性修改基本价格,只需将 FK ProductPricing 更改为 ProductType(“衬衫”)并有一个视图,该视图将根据类型的定价 + 属性计算产品价格,例如:

CREATE VIEW vProductWithPrice
AS
SELECT p.Id
     , (pp.Price 
       + SUM(CASE av.PriceModifierOperator
               WHEN '-' THEN -av.PriceModifierValue
               WHEN '+' THEN +av.PriceModifierValue
               WHEN '%' THEN pp.Price * av.PriceModifierValue / 100.0
               ELSE 0
             END)
       ) AS Price
  FROM Products p
  JOIN ProductTypes pt
    ON p.ProductTypeId = pt.ProductTypeId
  JOIN ProductPricing pp
    ON pp.ProductTypeId = pt.ProductTypeId
   AND pp.TerminationDate IS NULL -- currently active
  JOIN ProductAttributes pa
    ON pa.ProductId = p.ProductId
  JOIN AttributeValue av
    ON av.AttributeValueId = pa.AttributeValueId
 GROUP BY p.Id, pp.Price

在这里,我使用 AttributeValue 之类的字段,例如:

  - AttributeValueId
  - AttributeId (link to e.g. size)
  - Value (small/large/etc.)
  - PriceModifierOperator (+, -, %)
  - PriceModifierValue

请注意,像 */ 这样的运算符需要一些非常繁重的工作,因为:

  1. 有需要考虑的顺序(您是仅适用于基本价格,还是在属性之后,或者可能在某些属性之后但在其他属性之前;毕竟 5 * 3 + 1 + 2 != (5 + 1) * 3 + 2 != (5 + 1 + 2) * 3;和
  2. 聚合多个*运算符会很痛苦,你不能只做BasePrice * SUM(value),如果一个是*2,另一个是*3,那么你最终会得到BasePrice * 5而不是BasePrice * 6,并且使用EXP(SUM(LOG(Value))) 有一些注意事项

【讨论】:

  • 我想我需要库存/库存中的属性。我设想我可以拥有一件具有“尺寸”和“颜色”属性的产品“衬衫”。你会说为多属性创建单个产品会更好吗? (我正在想象产品视图中“衬衫”的选择下拉菜单)。我喜欢您对产品属性修饰符视图的想法。 * / 运算符听起来也不错,我想我无论如何都没有真正的应用程序。
  • 我会说将所有产品变体作为单独的产品肯定会更好,如果你想将它们分组,你有一个产品类型作为父级,如果需要,类别也可以 FK 到类型。使您的架构过于复杂将使其非常难以使用,无论是对于查询数据库的人还是将数据保存到其中的应用程序开发人员。根据我的经验,为了无限的灵活性而过度设计往往会适得其反。
猜你喜欢
  • 1970-01-01
  • 2018-03-31
  • 2022-01-20
  • 2011-12-24
  • 1970-01-01
  • 1970-01-01
  • 2011-02-26
  • 1970-01-01
  • 2014-10-23
相关资源
最近更新 更多