Lecture04-Redis-数据类型-List与Set

文章目录

    [toc]

    单词词性音标含义
    pushv./pʊʃ/推入(LPUSH/RPUSH 从头部/尾部插入,构建队列/栈)
    popv./pɒp/弹出(LPOP/RPOP 从头部/尾部取出并删除)
    rangen./v./reɪndʒ/范围(LRANGE key 0 -1 取全部元素)
    membern./ˈmembə(r)/成员(Set 集合中的元素)
    intern./ˈɪntə(r)/交集(SINTER 多个集合共有的元素)
    unionn./ˈjuːniən/并集(SUNION 合并去重)
    diffn./dɪf/差集(SDIFF 我有你没有的元素)
    randomadj./ˈrændəm/随机的(SRANDMEMBER/SPOP 随机取元素,抽奖用)
    duplicatev./n./ˈdjuːplɪkeɪt/重复(Set 自动去重,不允许重复成员)

    Lecture04-Redis-数据类型-List与Set

    1、List 类型

    1、什么是 List

    • 简单的字符串列表,按插入顺序排列。
    • 元素有序、可重复。
    • 底层:元素少用压缩列表 ziplist,元素多升级为快速链表 quicklist(多个小压缩块用指针串起来),头尾操作 O(1)。
    • 最大元素数量 2^32 - 1。
    List = "queue:task"
            ← left                          right →
            [ task3 ][ task2 ][ task1 ]
    

    2、常用命令

    命令功能
    lpush key v [v...]从左边插入一个或多个值
    rpush key v [v...]从右边插入一个或多个值
    lpop key / rpop key从左边/右边弹出一个值(取出即删除)
    lrange key 0 -1按索引取元素,0 左边第一个,-1 右边第一个
    llen key列表长度
    lindex key index按索引取单个元素(不删除)
    linsert key before/after 值 新值在指定值前/后插入
    lrem key 数量 值删除指定数量的某个值
    lset key index 值替换指定索引的值
    rpoplpush src dst从 src 右边弹出一个,插入 dst 左边(转圈/循环队列)

    3、操作演示

    # 从右插入三个
    127.0.0.1:6379> rpush queue:task task1 task2 task3
    (integer) 3
    127.0.0.1:6379> lrange queue:task 0 -1
    1) "task1"
    2) "task2"
    3) "task3"
    
    # 从左边弹出一个(队列先进先出:先入先出)
    127.0.0.1:6379> lpop queue:task
    "task1"
    127.0.0.1:6379> lrange queue:task 0 -1
    1) "task2"
    2) "task3"
    
    # 长度
    127.0.0.1:6379> llen queue:task
    (integer) 2
    

    4、典型应用场景

    场景用法
    简单异步队列LPUSH 生产、BRPOP 阻塞消费(第 8 讲/结合)
    栈LPUSH+LPOP(后进先出)
    最新消息/动态列表LPUSH 新消息 + LTRIM key 0 N-1 只留最近 N 条
    消息转存RPOPLPUSH 做可靠队列(消费失败回队列)
    分页列表LRANGE key (page-1)*size page*size-1

    注意:List 不适合"按值查询"和"随机访问中间元素",那属于其它结构。


    2、Set 类型

    1、什么是 Set

    • String 类型的无序、去重集合(基于哈希表/dict 实现,内部类似 Java HashSet)。
    • 元素唯一,自动去重。
    • 最大元素 2^32 - 1。
    • 天生支持集合运算:交集、并集、差集——这是它最大的价值。

    2、常用命令

    命令功能
    sadd key v [v...]添加一个或多个成员(已存在忽略)
    smembers key取出所有成员(无序)
    sismember key v判断是否存在(1/0)
    scard key返回成员数量
    srem key v [v...]删除指定成员
    spop key [n]随机弹出 n 个(取出即删除,抽奖消耗)
    srandmember key [n]随机取 n 个(不删除,抽奖预览)
    smove src dst v把成员从 src 移动到 dst
    sinter k1 k2 ...交集:多个集合共有的
    sunion k1 k2 ...并集:合并去重
    sdiff k1 k2差集:k1 有、k2 没有的("我有你没有")

    3、操作演示

    # 添加(重复会被去重)
    127.0.0.1:6379> sadd set:data aaa bbb ccc aaa aaa
    (integer) 3
    127.0.0.1:6379> smembers set:data
    1) "ccc"
    2) "bbb"
    3) "aaa"
    
    # 判断成员
    127.0.0.1:6379> sismember set:data aaa
    (integer) 1
    
    # 随机不删除
    127.0.0.1:6379> srandmember set:data 1
    "bbb"
    
    # 集合运算:共同关注
    127.0.0.1:6379> sadd user:1:follow userA userB userC
    (integer) 3
    127.0.0.1:6379> sadd user:2:follow userB userC userD
    (integer) 3
    127.0.0.1:6379> sinter user:1:follow user:2:follow
    1) "userB"
    2) "userC"
    127.0.0.1:6379> sdiff user:1:follow user:2:follow
    1) "userA"          # 我关注了、他没关注的
    

    4、典型应用场景

    场景用法
    关注 / 粉丝列表每个用户一个 Set 存关注/粉丝,SINTER 找共同关注
    去重流式数据、已读消息、收藏 ID 集合
    抽奖 / 随机发券SPOP(抽中即删)或 SRANDMEMBER(可重复抽)
    标签 / 兴趣用户打标签,按标签 SINTER 圈人
    点赞 / 签到SADD 点赞人集合,SCARD 看点赞数
    好友推荐(差集)SDIFF 找"认识的人里我还没关注的"

    3、本讲小结

    • List:有序可重复,头尾 O(1),做队列/栈/最新列表。
    • Set:无序去重,核心价值是集合运算,做关注/去重/抽奖/标签。
    • 高频命令:List 的 LPUSH/RPUSH/LPOP/RPOP/LRANGE,Set 的 SADD/SMEMBERS/SINTER/SUNION/SDIFF/SPOP。

    4、课堂练习

    1. 用 List 实现一个"消息队列":RPUSH 生产 3 条,LPOP 依次消费,观察先进先出。
    2. 用 List 做"最近 5 条浏览记录":LPUSH 后 LTRIM key 0 4。
    3. 用 Set 存储"点赞用户",给同一用户重复 SADD 两次,用 SCARD 确认去重。
    4. 建两组"关注集合",用 SINTER/SUNION/SDIFF 分别求共同关注、全部关注、单向关注。

    5、本节验证

    • 会用 LPUSH/RPUSH、LPOP/RPOP、LRANGE 操作 List,构建队列/栈 ✅
    • 会用 SADD/SISMEMBER/SRANDMEMBER/SPOP 操作 Set ✅
    • 会用 SINTER/SUNION/SDIFF 做集合运算(共同关注、抽奖等)✅
    • 理解 List 先进先出(队列)与 Set 自动去重特性 ✅
    end