You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DynamoDB单表设计优化咨询:减少冗余与GSI应用探讨

DynamoDB单表设计:冗余优化与访问模式适配方案

一、GSI确实可以减少冗余

你的思路是对的——用GSI替代主表中的冗余条目完全可行。当前设计里以TECH#tech_type为PK的条目如果是重复存储的发票副本,完全可以把这些冗余数据砍掉,改用GSI来支撑多维度查询。

核心逻辑是:主表只存一份完整的发票数据,把tech_type、proj_type作为发票的属性字段,然后通过GSI把这些属性映射为可查询的索引键,避免重复存储整份发票。

二、推荐的布局方案(适配你的三类访问模式)

方案1:主表仅存发票条目,GSI支撑多维度查询

这就是你提到的思路,具体落地:

  • 主表结构:
    • PK: INVOICE#<invoice_id>
    • SK: DETAILS(固定值,用于标识发票核心详情条目)
    • 属性:包含tech_type、proj_type、invoice_amount、invoice_date等所有发票业务字段
  • GSI1(适配访问模式2:按技术类型查发票):
    • GSI1-PK: TECH#<tech_type>
    • GSI1-SK: INVOICE#<invoice_id>
    • 投影策略:选择查询时需要的发票属性(比如只投影invoice_id、invoice_amount),或用全投影(简单但略占存储)
  • GSI2(适配访问模式3:按技术+类型组合查询):
    如果你的访问模式3是“查询某技术类型下某项目类型的所有发票”,可以这么设计:
    • GSI2-PK: TECH#<tech_type>
    • GSI2-SK: TYPE#<proj_type>#INVOICE#<invoice_id>
      查询时用PK=TECH#X且SK begins_with(TYPE#Y)就能快速筛选出目标发票;如果需要单独按项目类型查询,也可以把GSI2的PK设为TYPE#<proj_type>,SK设为TECH#<tech_type>#INVOICE#<invoice_id>,根据实际需求调整。

这个方案的优势是彻底消除主表冗余,所有发票数据只存一份,GSI按需投影,存储效率更高。唯一要注意的是GSI是最终一致性,如果你的业务对查询实时性要求极高(比如秒级内必须看到最新数据),可能需要权衡,但绝大多数业务场景都能接受。

方案2:主表保留轻量索引条目(强一致查询需求)

如果你的业务必须要求强一致查询(不能接受GSI的最终一致延迟),可以保留主表的多条目,但优化冗余程度——只存索引关联信息,不存完整发票副本:

  • 发票主条目:PK=INVOICE#<invoice_id>, SK=DETAILS,存完整发票数据;
  • 技术索引条目:PK=TECH#<tech_type>, SK=INVOICE#<invoice_id>,仅存invoice_id和proj_type等必要关联字段,不存发票金额、日期等详情;
  • 类型索引条目:PK=TECH#<tech_type>, SK=TYPE#<proj_type>#INVOICE#<invoice_id>,同样只存关联ID和必要分类字段。

查询时,先通过索引条目拿到invoice_id,再去主表查询完整发票数据。这种方案的冗余量很小(只有索引条目,没有完整发票副本),同时支持主表的强一致查询。

三、决策参考要点

  • 一致性要求:强一致选方案2,最终一致选方案1;
  • 查询灵活性:如果需要按项目类型跨技术查询,可以调整GSI的PK为TYPE#<proj_type>;
  • 成本权衡:方案1存储成本更低,方案2写入次数更多(每次创建发票要写3条主表条目)但查询一致性更强。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 22:04:52