Redis,常见存储类型以及在业务中如何选择

redis 存储常见类型

1. 字符串(Strings)

Redis中的字符串是一个基本的数据类型,用于存储和检索字符串值。

  • 用例:适合存储文本或数字,例如用户的姓名、电子邮件地址或者页面计数器。字符串类型也可以存储二进制数据,因此可以用来保存图片或序列化的对象。

  • 优势:操作简单,能够进行原子操作,如递增(INCR)。

    rust 复制代码
    // 保存字符串
    let _: () = conn.set("username", "alice").await.unwrap();
    
    // 获取字符串
    let username: String = conn.get("username").await.unwrap();

2. 列表(Lists)

Redis列表是字符串的集合,按插入顺序排序。

  • 用例:适合用于实现消息队列、活动日志、最近访问的项目列表等。列表支持在两端添加或移除元素,可以作为栈或队列使用。

  • 优势:提供快速的插入和删除操作。可以用作先进先出(FIFO)队列或后进先出(LIFO)堆栈。

    rust 复制代码
    // 向列表头部添加元素
    let _: () = conn.lpush("events", "login").await.unwrap();
    let _: () = conn.lpush("events", "logout").await.unwrap();
    
    // 获取列表元素
    let events: Vec<String> = conn.lrange("events", 0, -1).await.unwrap();

3. 集合(Sets)

集合是唯一字符串的无序集合。

  • 用例:用于存储没有特定顺序的唯一元素,例如标签、访问的IP地址或者社交网络中的好友列表。

  • 优势:能够快速地添加、删除和检查元素的存在,还可以执行集合间的操作,如并集、交集和差集。

    rust 复制代码
    // 向集合添加元素
    let _: () = conn.sadd("tags", "redis").await.unwrap();
    let _: () = conn.sadd("tags", "database").await.unwrap();
    
    // 获取所有集合成员
    let tags: Vec<String> = conn.smembers("tags").await.unwrap();

4. 有序集合(Sorted Sets)

有序集合类似于集合,但每个成员都有一个与之关联的分数。

  • 用例:适合用于需要按分数排序的数据,如排行榜、优先队列或存储具有排序权重的数据。

  • 优势:除了集合的基本操作外,还可以根据分数或字典顺序检索元素,以及获取特定范围内的元素。

    rust 复制代码
    // 向有序集合添加元素
    let _: () = conn.zadd("leaderboard", "alice", 100).await.unwrap();
    let _: () = conn.zadd("leaderboard", "bob", 200).await.unwrap();
    
    // 获取有序集合元素
    let leaderboard: Vec<(String, f64)> = conn.zrange_withscores("leaderboard", 0, -1).await.unwrap();

5. 散列(Hashes)

散列是键值对的集合,类似于编程语言中的字典或对象。

  • 用例:用于存储对象或多个相关数据点,如用户的多个属性(姓名、年龄、电子邮件等)。

  • 优势:可以一次性读取或写入多个字段,对于表示对象或聚合多个数据点非常有效。

    rust 复制代码
    // 向散列添加键值对
    let _: () = conn.hset("user:100", email", "[alice@example.com]()").await.unwrap();
    // 获取散列的所有键值对
    let user_info: HashMap<String, String> =conn.hgetall("user:100").await.unwrap();

6. 位图(Bitmaps)

位图是一个以比特为单位的数组,每个比特位可以独立设置或查询。

  • 用例:适合于需要标记存在或不存在的场景,如用户的签到情况、特定功能的开启关闭状态。

  • 优势:空间效率极高,适合于处理大量的布尔值。

    rust 复制代码
    // 在位图中设置位
    let _: () = conn.setbit("features", 0, true).await.unwrap();  // 启用功能0
    
    // 从位图获取位值
    let feature_enabled: bool = conn.getbit("features", 0).await.unwrap();

7. 超级日志(HyperLogLogs)

HyperLogLog是一种概率数据结构,用于高效地估计集合的基数(不同元素的数量)。

  • 用例:适用于需要估计大量数据的唯一元素数量的场景,如网站的独立访客数。

  • 优势:相对于传统的计数方法,HyperLogLog在内存使用上非常高效,特别是在处理大数据集时。

    rust 复制代码
    // 向HyperLogLog添加元素
    let _: () = conn.pfadd("pageviews", "user1").await.unwrap();
    let _: () = conn.pfadd("pageviews", "user2").await.unwrap();
    
    // 获取近似基数
    let unique_pageviews: i64 = conn.pfcount("pageviews").await.unwrap();

后端业务中选择合适的 Redis 数据类型以获得最佳的保存和查找效率,关键在于理解你的数据结构和使用场景。以下是一些常见的后端场景及推荐的 Redis 数据类型:

类型选择

1. 用户会话(User Sessions)

  • 推荐类型:散列(Hash)

  • 原因:散列可以存储用户会话对象的多个属性(如用户ID、令牌、最后访问时间等),并允许单独更新或检索特定字段。

    rust 复制代码
    let _: () = conn.hset("session:userid", "token", "abc123").await.unwrap();
    let _: () = conn.hset("session:userid", "last_access", "2023-01-01").await.unwrap();

2. 实时消息或事件队列(Real-time Messaging or Event Queuing)

  • 推荐类型:列表(List)

  • 原因:列表提供先进先出队列的特性,适合实时消息传递或任务队列。

    rust 复制代码
    let _: () = conn.rpush("events_queue", "event1").await.unwrap();
    let event: String = conn.lpop("events_queue").await.unwrap();

3. 访问计数器或频率限制(Access Counters or Rate Limiting)

  • 推荐类型:字符串(String)

  • 原因:字符串类型支持原子递增操作,适合用作计数器。

    rust 复制代码
    let _: () = conn.incr("page_view_count", 1).await.unwrap();
    let count: i64 = conn.get("page_view_count").await.unwrap();

4. 排行榜或分数排序(Leaderboards or Score Sorting)

  • 推荐类型:有序集合(Sorted Set)

  • 原因:有序集合根据分数自动排序,适合于排行榜等需要排序的数据。

  • Rust 示例

    rust 复制代码
    let _: () = conn.zadd("leaderboard", "user123", 2500).await.unwrap();
    let leaderboard: Vec<(String, f64)> = conn.zrange_withscores("leaderboard", 0, -1).await.unwrap();

5. 唯一值集合(如标签或分类)(Unique Value Collections like Tags or Categories)

  • 推荐类型:集合(Set)

  • 原因:集合提供唯一值存储,适合于需要去重的场景。

  • Rust 示例

    rust 复制代码
    let _: () = conn.sadd("tags", "redis").await.unwrap();
    let tags: Vec<String> = conn.smembers("tags").await.unwrap();

6. 多属性对象存储(Multi-attribute Object Storage)

  • 推荐类型:散列(Hash)

  • 原因:散列能够存储对象的多个字段,且可以独立地获取或更新这些字段。

    rust 复制代码
    let _: () = conn.hset("user:100", "name", "Alice").await.unwrap();
    let user: HashMap<String, String> = conn.hgetall("user:100").await.unwrap();

7. 功能标记或切换(Feature Flags or Toggles)

  • 推荐类型:位图(Bitmap)

  • 原因:位图适合存储布尔值,如功能的开启/关闭状态。

  • Rust 示例

    rust 复制代码
    let _: () = conn.setbit("features", 1, true).await.unwrap();
    let feature_on: bool = conn.getbit("features", 1).await.unwrap();

选择合适的类型取决于你的具体需求。如果你的数据结构简单(比如单个的键值对),字符串可能就足够了。对于更复杂的数据结构,如用户资料或会话信息,散列可能更合适。如果你的应用涉及到排行榜或者需要排序的数据,

相关推荐
Moment13 分钟前
Node.js v25.0.0 发布——性能、Web 标准与安全性全面升级 🚀🚀🚀
前端·javascript·后端
IT_陈寒27 分钟前
Vite 3.0 性能优化实战:5个技巧让你的构建速度提升200% 🚀
前端·人工智能·后端
程序新视界1 小时前
MySQL的整体架构及功能详解
数据库·后端·mysql
绝无仅有1 小时前
猿辅导Java面试真实经历与深度总结(二)
后端·面试·github
绝无仅有1 小时前
猿辅导Java面试真实经历与深度总结(一)
后端·面试·github
怪兽20142 小时前
Redis过期键的删除策略有哪些?
java·数据库·redis·缓存·面试
Victor3562 小时前
Redis(76)Redis作为缓存的常见使用场景有哪些?
后端
Victor3562 小时前
Redis(77)Redis缓存的优点和缺点是什么?
后端
摇滚侠5 小时前
Spring Boot 3零基础教程,WEB 开发 静态资源默认配置 笔记27
spring boot·笔记·后端
天若有情6737 小时前
Java Swing 实战:从零打造经典黄金矿工游戏
java·后端·游戏·黄金矿工·swin