如何在AWS ElastiCache(Redis)中按ID/交易号存储检索JSON数据
结构选择:优先用Hash结构,而非直接存JSON
直接存储JSON字符串的话,每次查询都要先解析整个JSON再提取目标数据,不仅性能低,还无法单独操作子字段。而Redis的Hash结构可以直接读写单个字段,更适配你的检索需求,同时能通过索引快速定位数据。
具体存储设计
1. 主对象(原JSON的id、status部分)存储
用Hash结构存储主对象的基础信息,键格式为tg:{id}(tg是transaction group的缩写,可根据业务调整):
HSET tg:100 id "100" status "complete"
2. 单个交易记录(items中的每条数据)存储
将每个item单独存为Hash,键格式为tx:{transactionNumber}(tx是transaction的缩写),同时关联主对象的id:
HSET tx:1 transactionNumber "1" type "A" group_id "100" HSET tx:2 transactionNumber "2" type "B" group_id "100"
3. 主对象与交易记录的关联索引
用Set结构存储每个主对象对应的所有交易编号,键格式为tg:{id}:items,方便通过主id快速获取所有关联交易:
SADD tg:100:items "1" "2"
检索操作示例
按id查询完整主对象及所有交易记录
- 获取主对象基础信息:
HGETALL tg:100
返回:1) "id" 2) "100" 3) "status" 4) "complete"
- 获取该主对象下的所有交易编号:
SMEMBERS tg:100:items
返回:1) "1" 2) "2"
- 批量获取所有交易记录:
HMGET tx:1 transactionNumber type group_id HMGET tx:2 transactionNumber type group_id
按transactionNumber查询单条记录
直接获取对应Hash的所有字段:
HGETALL tx:1
返回:1) "transactionNumber" 2) "1" 3) "type" 4) "A" 5) "group_id" 6) "100"
如果需要同时获取主对象的status,可通过group_id再查询tg:100。
为什么不选JSON结构?
如果用ElastiCache Redis的JSON模块存储整个JSON对象,虽然可以用JSONPath查询(比如JSON.GET order:100 '$.items[?(@.transactionNumber=="1")]'),但这种方式需要Redis解析整个JSON文档,当数据量较大或查询频繁时,性能远不如Hash+索引的方式。而且Hash结构更灵活,能单独更新某个交易记录或主对象的status,无需修改整个文档。
内容的提问来源于stack exchange,提问作者Tarun

