ZBLOG

redis zset如何存储一个对象?

在 Redis 中,ZSET(有序集合)的成员(member)通常是字符串类型,但可以通过 序列化 存储对象。以下是几种常见方法:


方法 1:将对象序列化为 JSON/二进制

步骤:

  1. 序列化对象(如 JSON、MessagePack、Protobuf 等)。
  2. 将序列化后的字符串作为 ZSETmember,并关联一个分数(score)。

示例(Python):

  1. import redis
  2. import json
  3. # 连接 Redis
  4. r = redis.Redis(host='localhost', port=6379)
  5. # 定义对象
  6. user = {"id": 1, "name": "Alice", "age": 30}
  7. # 序列化为 JSON
  8. user_json = json.dumps(user)
  9. # 存入 ZSET(分数为年龄)
  10. r.zadd("users:by_age", {user_json: user["age"]})
  11. # 查询年龄在 [20,40] 的用户
  12. results = r.zrangebyscore("users:by_age", 20, 40)
  13. for res in results:
  14. print(json.loads(res)) # 反序列化

方法2:使用 Hash + ZSET(推荐)

适用场景

需要频繁修改对象的某些字段时更高效。

步骤

  1. 用 Hash 存储完整对象(Key: obj:id, Field: Object Data)。
  2. 用 ZSET 存储对象的 ID + Score,仅用于排序和范围查询。

示例

  1. # Hash存储对象详情
  2. user_id = "user:1"
  3. r.hset(user_id, mapping={"name": "Alice", "age": "30"})
  4. # ZSET存储ID和分数(年龄)
  5. r.zadd("users:by_age", {user_id: user["age"]})
  6. # 查询时先获取ID列表,再批量从Hash取数据
  7. user_ids = r.zrangebyscore("users:by_age", min=20, max=40)
  8. for id in user_ids:
  9. print(r.hgetall(id)) # {"name": "Alice", ...}

方法3:自定义编码(如 MessagePack/Protobuf)

如果对性能要求高,可以用二进制协议替代 JSON:

  1. import msgpack
  2. # 序列化为 MessagePack
  3. user_bin = msgpack.packb({"id":1, "name":"Bob"})
  4. r.zadd("users:binary", {user_bin: score})

注意事项

  1. 更新问题

    • ZSET的 member (如JSON字符串)是不可变的。修改对象需先删除旧值,再插入新值。
    • Hash+ZSET方案更适合频繁更新的场景。
  2. 大对象优化

    • 避免存储过大的对象到ZSET中,优先用Hash分离数据。
  3. 分数重复性

    • ZSET的 score可以重复,但 member必须唯一。若需存重复对象,可在JSON中加入唯一标识符(如UUID)。

总结

方法 优点 缺点
直接存JSON 简单直接 更新麻烦
Hash+ZSET 易维护、适合更新 需多次查询
二进制编码 体积小、性能高 可读性差

根据业务需求选择合适的方式!


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=23676

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?