DynamoDB存储促销数据:索引方案与K-V拼接键选型咨询
先给你最关心的两个明确结论
- DynamoDB没有自动检测新字段创建二级索引的能力。不管是本地二级索引(LSI)还是全局二级索引(GSI),都必须手动显式创建;其中LSI只能在初次建表时定义,表上线后完全无法新增,只有GSI支持在表运行过程中动态添加,也需要人工触发创建操作,不存在自动建索引的内置功能。另外注意DynamoDB单表默认GSI配额是20个,刚好和你预估的新增查询字段数打平,真要给每个新字段单独建索引,不仅配额卡得紧,每个GSI都会额外产生存储、写入吞吐量成本,写入时要同步更新所有关联索引,开销会随索引数量线性上涨。
- 你提的两个方案都不是最优解,硬要比落地成本的话,盲目拼键存缓存的坑比按需加索引还多,长期维护成本更高。
为什么不推荐你列的两个方案
- 全字段拼接入独立K-V缓存的方案问题非常突出
首先你根本没法提前覆盖所有查询组合:如果后续有20个可查询字段,不同业务场景用的查询字段组合不一样,总不能把所有字段排列组合全拼一遍存缓存,组合数是指数级增长的,缓存浪费会极其严重。其次一致性维护成本极高:只要某条促销数据的任意一个查询字段更新,你就得找到所有包含这个字段的拼接键缓存做失效/更新,漏一条就会出脏数据,排查难度极大。最后这种方案只支持全键精确匹配,只要查询时少传一个字段、或者字段拼接顺序不对就完全命中不了,根本不支持范围查询、前缀模糊查询,灵活性为零。 - 给每个新增字段单独加二级索引的方案也不划算
除了之前说的配额、成本问题,单字段索引根本满足不了你现在就有的多字段组合查询需求:你当前查询维度是promotion_name+promotion_location组合,就算给两个字段分别建了GSI,DynamoDB也没法自动跨索引做关联过滤,要么全索引扫描要么过滤效率极低,达不到预期的查询性能。
适配你场景的低成本落地方案
用DynamoDB通用的单表设计思路就可以,完全不需要走两个极端:
- 主表直接设计复合主键:分区键可以选高离散度的通用维度(比如促销活动所属的业务线+上线月份,避免出现热分区),排序键提前预留拼接格式,比如
promotion_location#promotion_name,既支持两个字段的精确组合查询,也支持只传promotion_location时的前缀匹配查询,覆盖你当前的所有核心需求。 - 后续新增查询字段(比如
promotion_category)时,不要给每个新字段单独建GSI,而是把多个新增的常用查询维度拼到同一个GSI的排序键里,一个GSI就能覆盖34个查询维度的组合,一般35个GSI就能覆盖所有常用查询场景,远碰不到20个的配额上限,写入和存储成本也能压到很低。 - 缓存层不用提前拼接全量键,只给查询QPS最高的几个固定场景做缓存即可,缓存键直接用查询参数的序列化值,没命中就回源DynamoDB拉取数据再写缓存;数据更新时按业务主键删除对应关联缓存就行,维护成本非常低。
内容的提问来源于stack exchange,提问作者Jonathan
相关产品推荐
相关产品推荐

