Как спроектировать БД для продаж, которая включает атрибуты в продукты в инвентаре? - PullRequest
1 голос
/ 06 апреля 2019

Я пытаюсь создать базу данных, которая включает продукты, типы продуктов, атрибуты продуктов, в которых также хранятся данные о стоимости и запасах (запасах).Я хотел бы, чтобы это имело как можно меньше const / hardcoding, а также было бы масштабируемым для будущего.

Проблема, с которой я сталкиваюсь, заключается в том, что я хотел бы иметь несколько атрибутов, привязанных к продукту, некоторые из этих атрибутов могут привести к увеличению стоимости продукта, а также вести инвентаризацию продукта со всемиэти атрибуты.

Вот моя текущая диаграмма базы данных: db diagram

Я думал о добавлении столбца «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)

Было бы более целесообразно поместить совокупный объем предложения в представление / sproc?

Я ожидаю, что диаграмма будет обрабатывать следующие сценарии:

  1. Товар без, с одним или несколькими атрибутами
  2. Будьте готовы к атрибутам, изменяющим стоимость (от средней до большой)
  3. Необязательный модификатор стоимости
  4. Рассчитайте правильное количество продукта со всеми атрибутами, совпадающими в нашем инвентаре
  5. Надлежащим образом сохраните количество продукта, соответствующего каждому атрибуту, когда мы получим в нашей базе данных.'ProductStock'

1 Ответ

1 голос
/ 07 апреля 2019

Ваш 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)))
...