You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

门店关系型数据库设计优化:适配价格变更、折扣与营收统计需求

针对新增价格需求的数据库设计调整方案

嘿,作为数据库设计新手能搞定前面三个需求已经很赞啦!针对你新增的三个价格相关需求,咱们来一步步调整现有设计,确保能完美适配:

一、需求a:追踪产品价格变更历史

现有Product表的Price字段只能存当前价格,没法追溯历史。咱们新增一张ProductPriceHistory表来记录价格变更轨迹:

表结构:

  • PriceHistoryID (INT, 主键, 自增):每条价格变更记录的唯一标识
  • ProductID (VARCHAR/INT, 外键关联Product.ProductID):关联对应的产品
  • OldPrice (DECIMAL(10,2)):变更前的旧价格
  • NewPrice (DECIMAL(10,2)):变更后的新价格
  • ChangeTimestamp (DATETIME):价格变更的时间
  • ChangedBy (VARCHAR, 可选):记录操作价格变更的人员(比如管理员ID/名称)

逻辑说明:

每次修改Product表的Price字段时,先往ProductPriceHistory里插入一条记录,把旧价格、新价格和变更时间存下来。这样就能随时查询任意产品的价格变更历史,包括旧价格和变更时间啦。

查询示例:

-- 查询产品P001的所有价格变更记录
SELECT OldPrice, NewPrice, ChangeTimestamp, ChangedBy
FROM ProductPriceHistory
WHERE ProductID = 'P001'
ORDER BY ChangeTimestamp DESC;

二、需求b:特定门店-产品的限时折扣

要实现“特定门店特定产品的限时折扣”,咱们新增一张ProductShopDiscount表,专门管理门店级别的产品折扣:

表结构:

  • DiscountID (INT, 主键, 自增):每条折扣规则的唯一标识
  • ProductID (VARCHAR/INT, 外键关联Product.ProductID):关联折扣对应的产品
  • ShopID (VARCHAR/INT, 外键关联Shop.ShopID):关联折扣适用的门店
  • DiscountRate (DECIMAL(5,4)):折扣比例(比如0.75代表75折,1.0代表无折扣)
  • StartTime (DATETIME):折扣生效的开始时间
  • EndTime (DATETIME):折扣失效的结束时间
  • IsActive (BOOLEAN, 默认TRUE):标记该折扣是否启用(方便临时关闭而不用删除记录)

逻辑说明:

比如新店开业需要给产品A设置一周8折,就往这个表插一条记录:ProductID='A'ShopID='新店ID'DiscountRate=0.8StartTime=开业日期EndTime=开业后7天。销售时判断当前时间是否在折扣有效期内,再计算实际售价。

查询示例:

-- 查询门店S001中产品P001当前生效的折扣
SELECT DiscountRate
FROM ProductShopDiscount
WHERE ProductID = 'P001' 
  AND ShopID = 'S001'
  AND StartTime <= NOW() 
  AND EndTime >= NOW()
  AND IsActive = TRUE;

三、需求c:支持查询总营收

总营收基于销售出库(History.Status='OUT')的交易计算,为了保证历史营收的准确性(避免后续价格/折扣变更影响已发生的交易),咱们调整History表:

表结构调整:

新增TransactionPrice (DECIMAL(10,2))字段,记录该笔交易发生时的实际成交价格(如果是出库交易,就是原价或折扣后的价格;入库交易可以填采购价或NULL,根据业务需求)。

逻辑说明:

当发生销售出库时,先计算当时的实际价格(优先取门店折扣后的价格,没有折扣则用产品当前价格),然后把这个价格存入TransactionPrice字段。这样计算营收时直接求和即可,不用再反向追溯历史价格/折扣,效率更高且数据准确。

查询示例:

-- 查询所有门店的总营收
SELECT SUM(Quantity * TransactionPrice) AS TotalRevenue
FROM History
WHERE Status = 'OUT';

-- 按门店拆分查询营收
SELECT ShopID, SUM(Quantity * TransactionPrice) AS ShopRevenue
FROM History
WHERE Status = 'OUT'
GROUP BY ShopID;

额外优化:替换冗余的库存字段

你之前Product表的StockQuantity其实是冗余的——因为当前库存可以通过History表的出入库记录实时计算,而且更准确(避免手动更新库存导致的不一致)。建议去掉Product.StockQuantity,用下面的查询获取各门店当前库存:

SELECT 
  ShopID,
  ProductID,
  SUM(CASE WHEN Status='IN' THEN Quantity ELSE -Quantity END) AS CurrentStock
FROM History
GROUP BY ShopID, ProductID;

这样调整后,你的数据库就能完美覆盖所有新需求啦!如果有业务细节需要细化,比如折扣叠加规则、价格变更的审批流程等,可以再针对性调整~

内容的提问来源于stack exchange,提问作者John

火山引擎 最新活动