涉及嵌套属性时如何减小DynamoDB GSI项目大小
DynamoDB嵌套属性GSI投影优化方案
针对GSI不支持单独投影嵌套属性、需要压缩单条GSI条目体积适配1MB单次查询响应上限的场景,以下三个方案都可以实现单次查询拿到所需嵌套属性,同时最小化GSI条目体积,不需要二次回表请求:
- 写入时扁平化提取所需嵌套属性
数据写入基表时,直接把查询需要返回的嵌套字段,同步提取为独立的顶层属性,GSI选择KEYS_ONLY加这些单独提取的顶层属性做投影即可,完全不需要投影嵌套字段所属的整个大体积顶层对象。举个实际场景:如果顶层属性order_extra是个平均大小800字节的大对象,而业务查询只需要里面嵌套的pay_channel、refund_status两个字段,写入时就额外增加proj_pay_channel、proj_refund_status两个顶层字段,值和order_extra里的对应嵌套字段保持一致,GSI只投影这两个字段就行,单条GSI条目能省掉700多字节的无效空间。写入时把原字段和提取的投影字段放在同一个PutItem请求里提交,不会出现一致性问题。 - 紧凑打包所需嵌套属性为单一投影字段
如果需要的嵌套字段数量多,逐个提取成顶层属性太繁琐,可以在写入时把所有需要返回的嵌套字段挑出来,用MessagePack这类高压缩比的序列化方式打包成单个二进制类型的顶层属性(比如字段名就叫gsi_proj_bin),GSI只投影这一个字段,完全不投影原大体积顶层对象。查询拿到结果后在客户端做一次轻量反序列化就能拿到所有需要的嵌套字段,相比投影整个顶层对象通常能减少50%~80%的存储空间占用。注意打包时只塞查询需要的字段,不要带冗余内容。 - 短值嵌套属性复用GSI键空间
对于长度短、不需要做范围查询条件的目标嵌套属性,可以直接把字段值拼接到GSI的分区键或者排序键里,比如原GSI排序键是shop_id#create_ts,需要返回的嵌套属性order_status长度只有1字节,就可以把排序键调整为shop_id#create_ts#order_status,这部分字段完全不需要占用额外的投影属性空间,查询拿到键值后直接按分隔符拆分就能取到对应的值。注意拼接后GSI键的总长度不要超过DynamoDB规定的1024字节上限即可。
不建议采用「GSI只投影键、查询后再批量回表查基表取属性」的方案,该方案会翻倍消耗读容量,且无法在单次查询请求内拿到全量数据,达不到最大化单1MB响应返回条目数的目标。
内容的提问来源于stack exchange,提问作者Desk Reference
相关产品推荐
相关产品推荐

