如何在DynamoDB中设计1v1通话关系,实现用户全量通话列表查询?
1v1通话应用DynamoDB存储方案优化建议
更优方案:单条记录+全局二级索引(GSI)设计
每条通话仅存储一条记录,核心设计如下:
- 表主键(PK/SK):PK设为
CALL#{callId}(callId为通话唯一标识),SK设为#{timestamp}(通话时间戳,用毫秒级数值) - 核心属性:
caller_id(主叫用户ID)、callee_id(被叫用户ID)、direction(对主叫标记为OUT,被叫标记为IN)、status(通话状态)、timestamp(通话时间戳) - GSI配置:创建一个GSI,其PK为
USER#{user_id},SK为#{reverse_timestamp}#{direction}。其中reverse_timestamp是9999999999999 - timestamp,用于实现默认倒序排序(最新通话在前),投影所有需要查询的属性。
查询时,只需针对GSI执行Query操作:指定PK为USER#{目标用户ID},即可一次性获取该用户所有呼入、呼出通话,且天然按时间倒序排列,无需应用层额外处理。
原有方案对比
- 方案1(双记录存储):存在明显缺陷——数据冗余翻倍,每次更新通话状态/时间戳时需修改两条记录,极易出现数据不一致(如网络波动导致仅更新成功一条),同时增加了写操作的成本和复杂度,不推荐。
- 方案2(主叫PK+被叫GSI):需要分别查询呼入、呼出两组数据后在应用层合并排序,当数据量较大时,不仅会增加查询次数,合并排序的内存开销、分页逻辑复杂度都会显著提升,仅适合数据量极小的场景。
方案选择建议
优先采用上述的单条记录+GSI方案,兼顾读写性能与数据一致性。若受限于现有架构无法调整,只能在原有两个方案中选择,则优先选方案2,避免方案1的一致性风险。
内容的提问来源于stack exchange,提问作者anandsr-dev
相关产品推荐
相关产品推荐

