【Redis】--- 不同数据结构命令

本文详细介绍了Redis中的五种主要数据结构——字符串、列表、字典、集合和有序集合,以及各自适用的场景和常用命令。例如,字符串常用于缓存用户信息,列表可作为异步队列,字典适合存储用户对象,集合确保元素唯一性,有序集合则能按权重排序。此外,还讨论了高级命令如keys*和SCAN命令的使用及其原理。
摘要由CSDN通过智能技术生成


前言

【Redis】— 概念原理(类比闯关游戏理解持久化)


数据结构

string (字符串)

使用场景

一个常见的用途就是缓存用户信息。我们将用户信息结构体使用 JSON 序列化成字符串,然后将序列化后的字符串塞进 Redis 来缓存。同样,取用户信息会经过一次反序列化的过程。

命令

说明命令结果
设置值set name abner
取值get name
批量取值mget name name1
已有的key设置过期时间expire local 2
设置值并且设置过期时间setex local 20 Beijing
不存在则创建setnx local shanghai成功返回1,失败0
本地:0>set name abner
"OK"
本地:0>get name
"abner"
本地:0>set name1 condy
"OK"
本地:0>mget name name1
 1)  "abner"
 2)  "condy"
本地:0>mget name name1 name2
 1)  "abner"
 2)  "condy"
 3)  null
本地:0>set local BeJing
"OK"
本地:0>get local
"BeJing"
本地:0>expire local 2
"1"
本地:0>get local
null
本地:0>setex local 20 Beijing
"OK"
本地:0>get local
"Beijing"
本地:0>get local
"Beijing"
本地:0>get local
null
本地:0>setnx local shanghai
"1"
本地:0>get local
"shanghai"
本地:0>setnx local chongqing
"0"

原子计数

如果 value 值是一个整数,还可以对它进行自增操作。自增是有范围的,它的范围是 signed long 的最大最小值,超过了这个值,Redis 会报错

本地:0>set day 1
"OK"
本地:0>incr day
"2"
本地:0>get day
"2"
本地:0>incrby day 5
"7"
本地:0>incrby day -5
"2"
本地:0>set day 9223372036854775807
"OK"
本地:0>incrby day
"ERR wrong number of arguments for 'incrby' command"

list (列表)

使用场景

类似于java中的链表,增删快,查找慢。当列表中弹出最后一个元素,该数据结构自动被删除,内存被回收。通常用作异步队列使用

  • 右边进左边出:队列
  • 右边进右边出:栈

命令

说明命令结果
右进设置值rpush books python java c++ go
list长度llen books
左弹出数据lpop books
左获取list中的元素lrange books 0 -1
左获取list中的元素lrange books 0 -1
右弹出数据rpop books
本地:0>rpush books python java c++ go
"4"
本地:0>llen books
"4"
本地:0>lpop books
"python"
本地:0>lpop books
"java"
本地:0>lpop books
"c++"
本地:0>lpop books
"go"
本地:0>lpop books
null
本地:0>get books
null
本地:0>rpush books python java c++
"3"
本地:0>get books
"WRONGTYPE Operation against a key holding the wrong kind of value"
本地:0>lrange books 0 -1
 1)  "python"
 2)  "java"
 3)  "c++"
本地:0>lrange booke 1 2

本地:0>lrange books 1 2
 1)  "java"
 2)  "c++"
本地:0>rpush books go
"4"
本地:0>lrange books 0 -1
 1)  "python"
 2)  "java"
 3)  "c++"
 4)  "go"
本地:0>lpush books asd
"5"
本地:0>lrange books 0 -1
 1)  "asd"
 2)  "python"
 3)  "java"
 4)  "c++"
 5)  "go"
本地:0>rpop books
"go"
本地:0>

hash (字典)

使用场景

类似于java中的HashMap,同样的数组 + 链表二维结构。第一维 hash 的数组位置碰撞时,就会将碰撞的元素使用链表串接起来
hash 结构也可以用来存储用户信息,不同于字符串一次性需要全部序列化整个对象,hash 可以对 用户结构中的每个字段单独存储。这样当我们需要获取用户信息时可以进行部分获取。而以整个字符串的形式去保存用户信息的话就只能一次性全部读取,这样就会比较浪费网络流量。 hash 也有缺点,hash 结构的存储消耗要高于单个字符串,到底该使用 hash 还是字符串,需要根据实际情况再三权衡。

命令

说明命令结果
设置值hset company name "CIH"
获取对象所有属性hgetall company
批量设置对象属性hset company business "房地产" staff "程序猿&程序媛"
获取对象属性个数hlen company
本地:0>hset company name "CIH"
"1"
本地:0>hset company local "郭公庄地铁站"
"1"
本地:0>hgetall company
 1)  "name"
 2)  "CIH"
 3)  "local"
 4)  "郭公庄地铁站"
本地:0>hlen company
"2"
本地:0>hget company local
"郭公庄地铁站"
本地:0>hset company business "房地产" staff "程序猿&程序媛"
"2"
本地:0>hgetall company
 1)  "name"
 2)  "CIH"
 3)  "local"
 4)  "郭公庄地铁站"
 5)  "business"
 6)  "房地产"
 7)  "staff"
 8)  "程序猿&程序媛"
本地:0>

set (集合)

使用场景

相当于 Java 语言里面的 HashSet,它内部的键值对是无序的唯一的。它的内部实现相当于一个特殊的字典,字典中所有的 value 都是一个值NULL。 当集合中最后一个元素移除之后,数据结构自动删除,内存被回收。

命令

说明命令结果
设置值sadd infos java
批量设置值sadd infos c++ go
获取set中所有值smembers infos
判断某个值是否存在sismember infos go
获取长度scard infos
弹出值spop infos
本地:0>sadd infos java
"1"
本地:0>sadd infos python
"1"
本地:0>sadd infos c++ go
"2"
本地:0>smembers infos
 1)  "go"
 2)  "python"
 3)  "c++"
 4)  "java"
本地:0>sismember infos go
"1"
本地:0>scard infos
"4"
本地:0>spop infos
"c++"
本地:0>

zset (有序集合)

使用场景

zset 似于 Java 的 SortedSet 和 HashMap 的结合体,一方面它是一个 set,保证了内部 value 的唯一性,另一方面它可以给每个 value 赋予一个 score,代表这个 value 的排序权重。
zset 可以用来存粉丝列表,value 值是粉丝的用户 ID,score 是关注时间。我们可以对粉丝列表按关注时间进行排序。
zset 还可以用来存储学生的成绩,value 值是学生的 ID,score 是他的考试成绩。我们可以对成绩按分数进行排序就可以得到他的名次。

命令

说明命令结果
设置值zadd car 100 "劳斯莱斯"
获取全部值升序zrange car 0 -1
获取全部值降序zrevrange car 0 -1
获取长度zcard car
获取权重zscore car "布加迪"
获取某个值排名zrank car "兰博基尼"
根据分值区间遍历zrangebyscore car 0 87
移除某个元素zrem car "法拉利"
本地:0>zadd car 100 "劳斯莱斯"
"1"
本地:0>zadd car 90 "迈巴赫"
"1"
本地:0>zadd car 80 "布加迪"
"1"
本地:0>zadd car 85 "兰博基尼"
"1"
本地:0>zrange car 0 -1
 1)  "布加迪"
 2)  "兰博基尼"
 3)  "迈巴赫"
 4)  "劳斯莱斯"
本地:0>zrevrange car 0 -1
 1)  "劳斯莱斯"
 2)  "迈巴赫"
 3)  "兰博基尼"
 4)  "布加迪"
本地:0>zcard car
"4"
本地:0>zscore car "布加迪"
"80"
本地:0>zadd car 85.5 "法拉利"
"1"
本地:0>zrange car 0 -1
 1)  "布加迪"
 2)  "兰博基尼"
 3)  "法拉利"
 4)  "迈巴赫"
 5)  "劳斯莱斯"
本地:0>zscore car "法拉利"
"85.5"
本地:0>zrange car "劳斯莱斯"
"ERR wrong number of arguments for 'zrange' command"
本地:0>zrank car "布加迪"
"0"
本地:0>zrank car "兰博基尼"
"1"
本地:0>zrangebyscore car 0 87
 1)  "布加迪"
 2)  "兰博基尼"
 3)  "法拉利"
本地:0>zrangebyscore car -inf 87 withscores
 1)  "布加迪"
 2)  "80"
 3)  "兰博基尼"
 4)  "85"
 5)  "法拉利"
 6)  "85.5"
本地:0>zrem car "法拉利"
"1"
本地:0>zrem car "wuxiao"
"0"

高级命令

获取全部Key

说明命令缺点
获取全部Keykeys *当redis数据量比较大时,性能比较差
渐进式遍历键SCAN cursor [MATCH pattern] [COUNT count]通过游标分步进行的,不会阻塞线程

渐进式遍历键

参数

  • cursor :整数值,光标值
  • MATCH :key 的正则模式
  • COUNT :限定服务器单次遍历的字典槽位数量(下图中绿色部分)

原理分析

在 Redis 中所有的 key 都存储在一个很大的字典中,这个字典的结构和 Java 中的 HashMap 一样,是一维数组 + 二维链表结构,第一维数组的大小总是 2^n(n>=0),扩容一次数组大小空间加倍,也就是 n++。
在这里插入图片描述

scan 的遍历顺序非常特别。它不是从第一维数组的第 0 位一直遍历到末尾,而是采用了高位进位加法来遍历。之所以使用这样特殊的方式进行遍历,是考虑到字典的扩容和缩容时避免槽位的遍历重复和遗漏。
普通加法和高位进位加法的区别
高位进位法从左边加,进位往右边移动,同普通加法正好相反。但是最终它们都会遍历所有的槽位并且没有重复。
————————————————
版权声明:本文为CSDN博主「damanchen」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/damanchen/article/details/89314930

Redis中的Scan命令的使用

Info:查看redis服务运行信息,分为 9 大块,每个块都有非常多的参数,这 9 个块分别是: 
Server 服务器运行的环境参数 
Clients 客户端相关信息 
Memory 服务器运行内存统计数据 
Persistence 持久化信息 
Stats 通用统计数据 
Replication 主从复制相关信息 
CPU CPU 使用情况 
Cluster 集群信息 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Abner G

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值