数据库设计头脑风暴:销售价格

时间:2012-01-27 15:49:46

标签: c# sql linq-to-sql database-design e-commerce

我需要创建一个数据库解决方案来提供产品折扣。

当前表:

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. 使用a折扣指定ProductTypeId的所有产品 在上个月内发布日期。
  4. #2的挑战性方面不是文字示例,而是考虑到将来添加新字段时的长期可扩展性。

    由于ReleaseDate,我很难理解如何处理#3。

    下面,在我意识到我需要来到Stackoverflow之前,我是在心理上想到的。您可以看到,由于明确包含的列,刚性结构将不允许良好的可伸缩性 - 如果我们将来添加新条件,那么这些列将需要添加到表中 - 更不用说它甚至不处理发布日期要求。

    新表:

    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 个答案:

答案 0 :(得分: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和时髦的计算,您应该能够获得所有产品/类型的列表以及任何特定时间的折扣价格......

答案 1 :(得分:1)

我最终使用我的原始设计,当我使用linq查询数据库时,我使用方法获得“DiscountedPrice”。该方法运行自己的查询并在返回结果之前对其执行条件逻辑。因此,这使我可以选择让我的代码执行我的查询无法执行的其他工作。我还为特殊的ProductPriceDiscountIds创建了一个Enum类,因此可以轻松识别它们。我希望这可以帮助那些发现自己处于类似情况的人 - 到目前为止它对我来说非常好。