Redis学习笔记(二)-四种复合数据类型

本文介绍了Redis的四种高级数据类型:散列、列表、集合和有序集合。散列可存储复杂的键值对,适合表达多种数据类型;列表使用双向链表,适合存储有序的字符串列表;集合是无序且不重复的元素集合,常用于成员关系判断;有序集合则支持按分数排序,适用于需要排序的数据场景。文中还列举了各种数据类型的常用命令和应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


Redis学习笔记(二)-四种复合数据类型

继续上次的进行,第一篇重要学习了Redis的一些基本概念和基本操作语句,对Redis有了一个大概的认识,并且会简单使用,第一篇中忘记说明Redis的安装方法,这个很简单,上官网下载安装包解压即可。

这一次主要展开学习一下Redis的四种高级数据类型:(除字符串外)
1. 散列类型
2. 列表类型
3. 集合类型
4. 有序集合类型

我的这些学习笔记都是自己花心思整理出来的干货,希望能对也在学习的你起到帮助的作用,也可以方便自己以后查看和复习。


散列类型
散列类型的含义就是一个key对应着一个value,而value内部是一系列的key-value合集(也就是一个散列表)。类似于下面这个示例:

这里写图片描述

散列可以理解为两层JSON的嵌套,这种数据类型在现实中可以存储和表达很多类型的数据,是key-value数据库数据格式的一种基础升级,可以用散列存储一些较为复杂的数据,就比如上面的这个汽车的例子,这样存储以来,就可以通过car:2这个键直接获取到一系列描述这个键的键值对。

比如用散列来存储一篇博客:

这里写图片描述

这就是存储一个更为复杂的数据的例子,可以看出来,在现实网络环境中,绝大多数的数据对象都可以抽象成一个散列来存储。这也就是为什么散列在Redis里有着很基础也很重要的作用。


下面简单介绍下散列的一些基本命令,可以覆盖到绝大多数应用场景
散列的命令:

  1. 插入散列数据
    HSET car price 500
    HSET car name BMW

  2. 查询散列
    HGET car name

  3. 同时插入多个散列
    HMSET key field1 value1 field2 value2

  4. 获取散列的key所对应的所有键值对
    HGETALL key

  5. 判断散列中是否存在一个字段
    HEXISTS key field

  6. 当字段不存在时,插入字段,存在时不做操作。该命令也是原子操作
    HSETNX key field value

  7. 只获取散列中的字段
    HKEYS key

  8. 只获取散列中的值
    HVALS key

  9. 获取key中的字段数量
    HLEN key

总结:
可以通过以上的命令和介绍看出来,散列是一个升级版的key-value,是一个我们理解的嵌套的JSON数据,它在现实场景中可以更灵活的表达更多的数据类型和抽象对象。在维护上来看,它也是要比字符串更方便维护,所以任何复杂对象都可以用散列来表达和封装,而简单的单属性的内容就可以直接用字符串来存储。


列表类型

列表类型可以存储一个有序的字符串列表(list),列表类型内部使用的是双向链表,这样访问头和尾的数据的速度就会非常快。

命令:

  1. 向列表两端增加元素
    LPUSH key value
    RPUSH key value

    还可以同时增加多个元素:
    LPUSH numbers 1
    LPUSH numbers 2 3
    [3,2,1]

    RPUSH numbers 0 -1
    [3,2,1,0,-1]

  2. 从列表两端弹出元素
    LPOP key
    RPOP key

    弹出操作分两步:第一步将左边或者右边元素从列表中移除,第二步返回被移除的元素。

  3. 获取列表中的元素个数
    LLEN key
    这个命令类似于传统SQL语句中的 select conut(*) from table, 但是LLEN的复杂度是1,Redis直接会读取现成的值。而不像部分关系型数据库需要再次遍历该表的所有记录进行统计。

  4. 获取指定范围的元素
    LRANGE key 0 2
    获取从左边开始的编号从0 到 2 的元素。如果索引超出指定范围,而LRANGE不会写LPOP那样删除该片段。
    支持负索引,-1 代表右边第一个 -2代表右边第二个,以此类推。

  5. 删除指定的key
    LREM key count value
    删除key对应列表中从左边开始前count个值为value的内容。 count等于0 删除所有元素, count < 0 则取其绝对值

  6. 获取指定下标元素
    LINDEX number 0 从左边的下标0开始算,获取指定下标的元素。如果索引为-1 则代表最右边元素。

  7. 更改列表中指定的值
    LSET number 1 7 把number序列中的下标为1的元素设置为7

  8. 删除指定范围内的值
    LTRIM number 1 2 删除列表中除了下标 1 2 范围内的所有元素。

    LTRIM和LPUSH经常一起使用。比如记录日志时,我们只希望保留最近100条记录。则可以这样:
    LPUSH log $newlog
    LTRIM 0 99
    每次增加日志后都trim一下,保证列表中只有100条记录。

  9. 在指定元素的左边或右边插入元素
    LINSERT key before|after value1 value2
    向key列表中插入一个元素,从左边开始查找到元素value1,在value1的左边(before)或者右边(after)插入value2

  10. 从一个列表中弹出元素插入到另一个列表
    RPOPLPUSH source destination
    从source列表中的右边弹出一个元素插入到destination列表中的左边,并最终返回这个值。整个过程是原子的。当source和destination相同时,RPOPLPUSH会不断的把队尾元素转移到队首。

总结:
列表就相当于链表一样,可以存储很多有序的数据,并且可以快速的找到你所需要的数据,列表类型在现实应用中也是有着很广泛的应用。


集合类型

集合中的每个元素都是不同的,且没有顺序。一个集合类型键可以存储最多 2^32 -1 个字符串。集合类型常用的操作有插入,删除,判断元素是否存在。由于集合在Redis内部实现是由hash table实现的,所以这些操作的复杂度都是O(1)的。最方便的是多个集合类型键之间还可以进行交集,并集和差集的运算。

命令:

  1. 增加元素
    SADD key number [number …]
    如果集合中存在这个元素,则忽略其,加入剩余不存在的元素。

  2. 删除元素
    SREM key number [number …]
    删除元素时,如果要删除的元素不存在集合中,则忽略。删除其他的元素。

  3. 获取集合中所有元素
    SMENBERS key

  4. 判断元素是否在集合中
    SISMEMBER key number
    这个命令的复杂度是O(1),存在则返回1,不存在则返回0

  5. 集合差集运算
    SDIFF key [key …]

    {1,2,3} - {2,3,4} = {1}
    {2,3,4} - {1,2,3} = {4}
    {1} - {2,3} = {1}
    多个集合连续运算是先计算前两个,用结果再后第三个计算,以此类推。

  6. 集合交集运算
    SINTER key [key …]

    {1,2,3} ∩ {2,3,4} = {2,3}

  7. 并集运算
    SUNION key [key …]
    {1,2,3}∪{2,3,4} = {1,2,3,4}

  8. 获取集合中元素个数
    SCARD key

  9. 进行集合运算并将结果存储
    SDIFFSTORE destination key [key …]
    SINTERSTORE destination key [key …]
    SUNIONSTORE destination key [key …]

  10. 随机获取集合中的元素
    SRANDMEMBER key [count]

    SRANDMEMBER abcdefg 2
    可能返回任意两个字母

  11. 从集合中弹出一个key
    SPOP key
    pop出来后就相当于删除了。

总结:
集合就相当于编程语言中的Set,是一系列元素的集合,但是无序的,而且不能有重复的数据。同样的,在现实环境下有着很广泛的应用。


有序集合

最后,来说一下有序集合。
列表是通过链表来实现的,它获取靠近两端的数据非常快,但是获取中间的的数据会比较慢。所以它更适合实现如“新鲜事”,“日志”等很少访问中间元素的应用。

有序集合是通过散列表和跳跃表实现的,所以即使读取位于中间的数据也很快。列表不能简单的调整某个元素的位置,但有序集合可以(通过更改这个元素的分数)有序集合比列表更耗内存。

命令:

  1. 增加元素
    ZADD key score number
    eg: ZADD scoreboard 89 Tom 67 Peter 100 David

  2. 如果重复插入相同的内容,则覆盖
    ZADD scoreboard 76 Peter

    插入的分数还支持浮点数。以及正无穷(+inf)和负无穷(-inf)

  3. 获取元素分数
    ZSCORE scoreboard Tom

  4. 获取排名在某个范围内的列表
    ZRANGE scoreboard 0 2
    ZRANGE scoreboard 1 -1 (-1代表最后一个元素)

    需要返回元素和分数:
    ZRANGE scoreboard 0 -1 WITHSCORES

  5. 获取指定分数范围内的元素
    ZRANGEBYSCORE scoreboard 80 100

    包含80,不包含100
    ZRANGEBYSCORE scoreboard 80 (100

  6. 限制查询出来的条数
    ZRANGEBYSCORE scoreboard 80 (100 limit 3

  7. 查询分数低于100的前三个
    ZREVRANGEBYSCORE scoreboard 100 0 limit 0 3
    100 0 代表查询范围从100开始到0,0 3 代表对查询出来的结果取三个元素,从编号为0的开始取

  8. 增加某个元素的分数
    ZINCRBY scoreboard 4 Jerry
    返回更改后的分数

    减少指定元素的分数
    ZINCRBY scoreboard -4 Jerry

  9. 获得集合中元素数量
    ZCARD key

  10. 删除一个或多个元素
    ZREM key number [number …]

  11. 按照排名范围删除元素
    ZADD test 1 a 2 b 3 c 4 d 5 e 6 f

    ZREMRANGEBYRANK 0 2 – 删除掉了a b c

  12. 获得指定元素排名
    ZRANK scoreboard Peter – 分数最小排名为0
    ZREVRANK scoreboard Peter – 分数最大排名为0

  13. 有序集合的交集
    ZINTERSTORE destination numkeys key [key …] [WEIGHT weight [weight]] [AGGREGET SUM|MIN|MAX]

    numkeys 指后面有几个key来做交集操作
    1) AGGREGET 是SUM时(默认SUM), 每个交集计算的是相同元素的分数和,然后存放到destination键中。

    ZADD sortedSet1 1 a 2 b
    ZADD sortedSet2 2 a 4 b

    ZINTERSTORE sortedSetsResult 2 sortedSets1 sortedSets2
    (Integer) 2

    ZRANGE sortedSetsResult 0 -1 WITHSCORES
    a
    3
    b
    6

    2) 当AGGREGATE是MIN时,destination元素中的分数是每个参与计算的集合中该元素分数最小值

    ZINTERSTORE sortedSetsResult 2 sortedSets1 sortedSets2 AGGREGATE MIN
    a
    1
    b
    2

    3) 当AGGREGATE是MAX时,destination元素中的分数是每个参与计算的集合中该元素分数最大值

    ZINTERSTORE sortedSetsResult 2 sortedSets1 sortedSets2 AGGREGATE MAX
    a
    2
    b
    4

    4) ZINTERSTORE还能通过WEIGHTS参数设置每个集合的权重,来按权重计算每个相交集合中的键所占得比例

    ZINTERSTORE sortedSetsResult 2 sortedSets1 sortedSets2 WEIGHT 1 0.1
    a
    1.2
    b
    2.4

    并集的操作ZUNIONSTORE与ZINTERSTORE的用法一样。

总结:
有序集合可以存储很多需要排序的内容,网络中有大量的场景是需要将数据进行排序的,所以有序集合的应用非常广泛。例如按照文章访问量排序,按照口碑排序购买商品等等。有序集合的交并差也是很方便使用的。这样在一些购买推荐,别人在查看的内容等等推送信息上,都可以用到有序集合来实现。


这一篇主要学习了除了字符串以外的四种常见的复合数据类型,并且详细介绍了每种数据类型的含义使用场景以及相关命令。下一篇来学习一下Redis的事务。

(未完待续)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值