如何实现DynamoDB中Shop表max_price字段的实时更新?
解决DynamoDB中Shop表max_price同步更新的简易方案
问题回顾
现有两个DynamoDB表:
- Shop表:
Shop_id(分区键)、Shop_Name - Product表:
Product_id(分区键)、Product_Name、Shop_Id、Price
需求是给Shop表新增max_price字段,随Product表的价格更新自动同步,核心难点是当原最高价格商品降价时,快速找到下一个最高价,且不能给Product表创建GSI,仅允许新增属性。已有堆方案需要额外建2个表,以下是更简易的替代方案:
方案一:用标记属性跟踪当前最高价商品
只需要给Product表新增一个布尔属性is_current_max,配合DynamoDB事务保证一致性:
操作逻辑
新增/涨价商品时:
- 查询对应Shop的当前
max_price - 若新价格 > 当前
max_price:- 启动事务:更新Shop的
max_price为新价格;将原最高价商品的is_current_max设为false;将当前商品的is_current_max设为true
- 启动事务:更新Shop的
- 若新价格 == 当前
max_price:直接将当前商品的is_current_max设为true - 若新价格 < 当前
max_price:仅更新商品的Price字段即可
- 查询对应Shop的当前
商品降价时:
- 先判断该商品是否标记为
is_current_max:- 若不是:仅更新商品的
Price字段 - 若是:扫描该Shop下所有Product(通过
Shop_Id过滤),找出最高价格;启动事务:更新Shop的max_price为新最高价;将对应商品的is_current_max设为true,其余同Shop的商品设为false
- 若不是:仅更新商品的
- 先判断该商品是否标记为
优势
- 无需额外建表,仅新增一个Product属性
- 大部分场景(非最高价商品更新)操作速度快,只有当原最高价商品降价时才需要扫描,适合商品数量不多的店铺
方案二:在Shop表维护价格统计集合
给Shop表新增两个属性:
price_count:Map类型,key为价格数值,value为该价格对应的商品数量price_candidates:Set类型,存储该店铺所有存在的价格值(去重)
操作逻辑
所有操作均通过DynamoDB事务执行,保证数据一致性:
新增商品:
- 查询Shop的
price_count和price_candidates - 若新价格不在
price_count中,将其加入price_candidates,并在price_count中设计数为1;否则将对应计数加1 - 更新Shop的
max_price为price_candidates中的最大值 - 写入新的Product记录
- 查询Shop的
更新商品价格:
- 查询要更新的Product的旧Price,以及Shop的
price_count、price_candidates、max_price - 对旧Price的计数减1:若计数变为0,从
price_candidates中移除该价格 - 对新Price的计数加1:若之前计数为0,将其加入
price_candidates - 更新Shop的
max_price为price_candidates中的最大值 - 更新Product的Price为新值
- 查询要更新的Product的旧Price,以及Shop的
优势
- 完全不需要扫描Product表,所有操作基于Shop表的统计属性完成
- 数据一致性由事务保证,适合商品数量较多的场景
方案三:简化版价格统计(仅维护最高价候选)
如果不想维护完整的价格集合,可以在Shop表只存当前最高价和次高价,以及对应价格的商品数量:
- 新增
current_max、current_max_count、second_max三个属性 - 操作逻辑类似方案二,但只跟踪前两名的价格和数量,进一步减少数据存储量
- 缺点是当次高价商品也被修改时,需重新扫描获取新的次高价,适合对存储成本敏感的场景
内容的提问来源于stack exchange,提问作者wolf
相关产品推荐
相关产品推荐

