Дизайн базы данных мозговой штурм: цены продажи - PullRequest
3 голосов
/ 27 января 2012

Мне нужно создать решение для базы данных, чтобы обеспечить скидку на продукт.

Текущие таблицы:

Products
Columns: ProductId, ProductTypeId, ReleaseDate

ProductPrices
Columns: ProductPriceId, ProductPriceTypeId (one product may have n prices), ProductId, Price

Мы хотим иметь возможность скидок по ProductId и / или ProductTypeId и / или ProductPriceTypeId и / или ReleaseDate.

Пример продаж:

  1. Скидка на один ProductId.
  2. Скидка на все товары с указанным ProductTypeId и ProductPriceTypeId.
  3. Скидка на все товары суказанный ProductTypeId с ReleaseDate в течение последнего месяца.

Сложный аспект # 2 не является буквальным примером, но с учетом долгосрочной масштабируемости в случае добавления новых полей в будущем.

Из-за ReleaseDate я озадачен тем, как справиться с № 3.

Ниже я мысленно придумал, прежде чем понял, что мне нужно прийти в Stackoverflow.Вы можете видеть, что жесткая структура не обеспечит хорошую масштабируемость из-за явно включенных столбцов - если мы добавим новые критерии в будущем, эти столбцы нужно будет добавить в таблицу - и не говоря уже о том, что она даже не обрабатываетТребование ReleaseDate.

Новая таблица:

ProductPriceDiscounts
Columns: ProductPriceDiscountId, ProductPriceId, ProductTypeId, ProductPriceTypeId, Discount, DiscountTypeId (1 for percentage, 2 for fixed)

Тогда я мог бы использовать что-то вроде этого, чтобы получить оценку:

from p in Products
join pp in ProductPrices on p.ProductId equals pp.ProductId
let ppd = (
    from ppd in ProductPriceDiscounts
        .WhereIf(ppd.ProductPriceId != null, ppd.ProductPriceId == pp.ProductPriceId)
        .WhereIf(ppd.ProductTypeId != null, ppd.ProductTypeId == pp.ProductTypeId )
        .WhereIf(ppd.ProductPriceTypeId != null, ppd.ProductPriceTypeId == pp.ProductPriceId)
    select ppd).FirstOrDefault()
where p.ProductId = productId
select new 
{
    ...,
    Price = pp.Price,
    Discount = pp.Discount,
    DiscountedPrice = 
        (ppd.DiscountTypeId == 1) ? 
            (pp.Price - (pp.Price * pp.Discount)) :
            (pp.Price - pp.Discount) :
}

Я включил только этот плохой пример, я пришелчтобы показать конечный результат того, как я должен быть в состоянии использовать эту новую функциональность дисконтирования продукта.Может ли кто-нибудь предложить совет для хорошего способа справиться с этой ситуацией?Спасибо.

Ответы [ 2 ]

2 голосов
/ 27 января 2012

Я бы сказал, что вам нужен отдельный DiscountDetail стол.Что-то вроде

   DiscountDetailID INT NOT NULL
   DiscountTypeID INT NOT NULL --(FK On Discount Types - maybe not necessary)
   DiscountProductTypeID INT NULL --(FK ON ProductType)
   DiscountProductID INT NULL --(FK ON Product)
   DiscountAmount INT NULL --(Some value related to %age reduction perhaps?)
   DiscountDateStart DATETIME NOT NULL
   DiscountDateEnd DATETIME NULL

С некоторыми прекрасными left join с и прикольными расчетами вы сможете получить список всех продуктов / типов и цены со скидкой в ​​любое конкретное время ...

1 голос
/ 13 февраля 2012

Я закончил с моим первоначальным дизайном, и когда я запрашиваю базу данных, используя linq to sql, я получаю Disc DiscPrice, используя метод.Метод выполняет собственный запрос и выполняет условную логику перед возвратом результатов.Так что это дает мне возможность заставить мой код выполнять дополнительную работу, которую мой запрос не сможет выполнить.Я также создал класс Enum для специальных ProductPriceDiscountIds, чтобы их можно было легко идентифицировать.Я надеюсь, что это поможет любому другому, кто окажется в подобной ситуации - пока он работает очень хорошо.

...