2012-01-27 5 views
3

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

Текущие столы:

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 не является буквальным примером, но учитывая долгосрочную масштабируемость в случае добавления новых полей в будущем.

Я столкнулся с тем, как обращаться с # 3 из-за ReleaseDate.

Ниже, это то, что я мысленно продумал, прежде чем понял, что мне нужно прийти в 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) : 
} 

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

ответ

1

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

2

Я бы сказал, что вам нужен отдельный стол 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 с и фанками расчетов вы должны быть в состоянии получить список всех продуктов/типов и скидки в любой конкретный момент времени ...