体育博彩应用DynamoDB建模:用户关联活跃池子查询方案咨询
体育博彩应用数据建模方案:获取用户参与的活跃池子
核心思路:反范式复制必要数据,利用GSI实现高效查询
DynamoDB这类NoSQL数据库的最优实践是通过复制数据避免多表关联查询,所以直接将池子的IsActive状态和必要展示字段复制到用户参与的关联记录中,配合GSI就能实现单步高效查询。
具体实现方案
- 调整Prediction记录结构:给每条Prediction记录添加
UserId(记录参与预测的用户ID),同时把对应池子的IsActive字段复制到该记录里,还可以同步池子的核心展示属性(比如池名称、赛事名称、预测截止时间等)。 - 创建专属GSI:
- GSI分区键(GSI1-PK):
UserId - GSI排序键(GSI1-SK):
Prediction#<PoolId>(或直接用PoolId,保证唯一性即可) - 投影属性:包含
IsActive、池子名称、赛事信息等首页需要展示的所有字段
- GSI分区键(GSI1-PK):
- 查询逻辑:
- 针对当前用户,查询该GSI,条件设为
UserId = 当前用户ID,同时过滤IsActive = true - 查询结果直接返回用户参与过的所有活跃池子的展示数据,无需再去主表二次查询
- 针对当前用户,查询该GSI,条件设为
替代方案:单独存储用户参与关系记录
如果不想复用Prediction记录,可以新增一类记录专门存储用户与池子的参与关系:
- 记录结构:
- PK:
User#<UserId> - SK:
ParticipatedPool#<PoolId> - 属性:
PoolId、IsActive、池子名称、赛事信息等
- PK:
- 查询方式:直接查询主表,条件为
PK = User#<当前用户ID>,SK以ParticipatedPool#开头,过滤IsActive = true,就能直接获取结果
为什么不推荐N+1查询?
如果不把IsActive复制到关联记录里,你需要先查用户所有参与的Prediction记录拿到PoolId,再逐个查主表的池子记录判断是否活跃。这种方式会产生大量额外查询,不仅延迟高,还会增加DynamoDB的读写成本,完全不符合NoSQL的设计思路。
内容的提问来源于stack exchange,提问作者Roger Thomas
相关产品推荐
相关产品推荐

