当前位置:首页 > 问答 > 正文

Redis里那些常用的数据类型和它们到底为啥这么受欢迎,聊聊应用上的好处

Redis之所以这么牛,很大程度上是因为它不像传统的关系型数据库(比如MySQL)那样,只有一种固定的表格方式来存数据,它提供了好几种灵活的数据结构,让你可以直接用这些结构来解决实际问题,就好像给你的工具箱里添置了各种专用工具,而不是只有一把万能扳手,这大大简化了程序代码,并且因为数据直接在内存里操作,速度飞快,下面我们就看看几个最常用的类型。

字符串(String)

这是最基本也是最常用的类型,你可以把它理解成一个能装下各种东西的“小盒子”,这个盒子不仅能放普通的文本字符串,还能放数字、甚至二进制数据(比如一张图片的序列化内容),它受欢迎的原因很简单:用途太广了。

  • 应用上的好处
    • 缓存(Cache)的绝对主力:这是Redis最经典的用法,比如一个网站的首页内容生成很耗时,就可以把生成好的整个HTML页面或者关键数据用String类型存到Redis里,并设置一个过期时间,下次再有用户访问,直接从Redis里拿,速度快如闪电,大大减轻了后端数据库的压力,根据Redis官方文档(Antirez, 《Redis设计与实现》)中的思想,这种简单的键值对模型对于缓存场景来说是最直接高效的。
    • 计数器:因为Redis提供了直接对数字进行增加(INCR)或减少(DECR)的命令,所以用它来做计数器特别方便,比如统计文章的阅读量、用户的点赞数、网站的在线人数等,你不需要先从数据库读出数字,在程序里计算,再写回去;只需要发一条INCR article:123:views这样的命令,Redis就帮你原子性地完成了,既快又不会出错。
    • 存储会话(Session):在Web开发中,用户登录后的信息(如用户ID、用户名)可以存成一个JSON字符串放在Redis里,并设置一个和浏览器Cookie对应的Key,这样应用服务器就变成了无状态的,可以轻松扩展,用户的登录状态也能在不同服务器间共享。

哈希(Hash)

如果说String是一个“小盒子”,那Hash就是一个“带有很多小抽屉的收纳盒”,它特别适合用来存储一个对象,比如一个用户有ID、姓名、年龄、邮箱等多个属性,如果用String存,你可能需要序列化成JSON,如果想修改其中一个字段就得整个替换,但用Hash,你可以把每个字段单独存为这个“收纳盒”里的一个键值对。

  • 应用上的好处
    • 存储对象信息:正如上面提到的,存储用户信息、商品信息、订单信息等拥有多个属性的对象是Hash的天然舞台,你可以单独获取(HGET)、修改(HSET)某个字段,非常灵活,网络传输的数据量也小,效率很高,在《Redis实战》(Josiah L. Carlson)这本书里,就强调了Hash在表示对象方面的优势。
    • 购物车:电商场景中,用户的购物车非常适合用Hash来表示,Key是用户ID,Field是商品ID,Value是商品数量,添加商品就是HINCRBY,删除商品就是HDEL,获取全部商品就是HGETALL,操作起来直观又高效。

列表(List)

List就是一个简单的字符串列表,按照插入的顺序排序,你可以从列表的左边(头部)或右边(尾部)添加或取出元素,像一个双向队列。

  • 应用上的好处
    • 消息队列:这是List一个非常流行的用法,生产者用LPUSH从左边放入任务消息,多个消费者用BRPOP从右边阻塞地获取任务,这样就实现了一个简单的分布式消息队列,用于解耦系统组件和进行异步处理,虽然现在有更专业的消息队列,但Redis List因其简单和高效,在很多场景下仍然是首选。
    • 最新消息列表:比如微博的时间线、新闻网站的最新文章列表,每次用户发布新内容,就用LPUSH把它塞到列表头部,然后用LTRIM命令只保留最新的1000条,这样要获取最新内容时,直接用LRANGE取前几条就行了,速度极快。

集合(Set)

Set是一个无序的集合,它的特点是里面的元素都是唯一的,不会重复,它提供了求交集、并集、差集等强大的集合操作。

  • 应用上的好处
    • 标签(Tag)系统:给一篇文章打标签,每个标签不能重复,用Set就非常合适,Key可以是article:123:tags,Value是{技术, Redis, 数据库}这样的标签集合,你可以轻松地添加标签、删除标签,还可以找出同时拥有“技术”和“Redis”两个标签的所有文章(这就是求交集操作)。
    • 共同好友/关注:在社交网络中,判断两个人共同的好友是谁,其实就是求两个用户好友集合的交集,Set的SINTER命令能直接完成这个任务,效率非常高。
    • 抽奖/秒杀中判断是否参与过:将所有参与活动的用户ID放入一个Set,因为Set的成员是唯一的,所以可以轻松判断某个用户是否已经参与过,防止重复参与。

有序集合(Sorted Set / ZSet)

这是Redis数据结构中的王牌之一,它和Set类似,保证成员的唯一性,但每个成员都会关联一个分数(Score),Redis会根据这个分数对成员进行从小到大的排序。

  • 应用上的好处
    • 排行榜:这是ZSet最经典的应用,比如游戏玩家的积分排行榜、微博的热搜榜,玩家ID是成员,积分或热度就是分数,你可以轻松地获取排名前N的玩家(ZREVRANGE),查看某个玩家的具体排名(ZREVRANK),操作非常简单直接,其实现原理(跳跃表)在《Redis设计与实现》中有详细描述,使其即使在数据量很大时,排名操作也很快。
    • 带权重的消息队列:普通List是先进先出,但有时需要优先处理重要的任务,你可以用ZSet,将任务优先级作为分数,执行时间作为另一个维度,消费者可以按照分数顺序来获取最重要的任务进行处理。
    • 时间轴:比如新闻按发布时间排序,时间戳就可以作为分数。

总结一下为啥它们这么受欢迎:

归根结底,Redis这些数据类型之所以能成为开发者手中的利器,是因为它们“建模自然,操作高效”,它们直接映射了我们在编程中经常需要处理的数据模型(如对象、列表、集合、排行榜),并且为这些模型提供了原子性的、高性能的操作命令,你不再需要像使用传统数据库那样,通过复杂的SQL和应用程序逻辑来模拟这些操作,而是直接使用Redis现成的“武器”,这让开发变得简单,让系统性能得到巨大提升,这种设计哲学,使得Redis远远超出了一个简单键值存储的范畴,成为了一个多功能的数据结构服务器。

Redis里那些常用的数据类型和它们到底为啥这么受欢迎,聊聊应用上的好处