04_Redis十大数据类型
本笔记来源于:尚硅谷Redis零基础到进阶,最强redis7教程,阳哥亲自带练(附redis面试题)
b站视频
文章来自:
https://github.com/loneasing/mynote
Redis十大数据类型
redis中的数据都是用k-v键值对存储的,所有的key都是String类型,所说的十大==数据类型指的是value值的数据类型==。
准确来说这十大数据类型只有==六大数据类型==,分别是==String、List、Hash、Set、Zset、Stream==。
其余的四种是对这数据类型封装出来的数据结构,分别是Bitmap(String)、HyperLogLog(String)、Geospatial(Zset)、BitField(String)。
一. Stirng(字符串)
string是redis最基本的类型,一个key对应一个value。
string类型是二进制安全的,意思是redis的string可以包含任何数据,比如jpg图片或者序列化的对象 。
string类型是Redis最基本的数据类型,一个redis中字符串value最多可以是512M
官网地址: https://redis.io/docs/data-types/strings/
字符串
String类型,也就是字符串类型,是Redis中最简单的存储类型,单key单value结构。
其value是字符串,不过根据字符串的格式不同,又可以分为3类:
String:普通字符串
int:整数类型,可以做自增、自减操作
float:浮点类型,可以做自增、自减操作不管是哪种格式,底层都是字节数组形式存储,只不过是编码方式不同。字符串类型的最大空间不能超过512m.
String类型的常用命令:
SET和GET
1 |
|
**set key value [可选参数]
**:添加或者修改一个String类型的键值对
**get key
**:根据key获取String类型的value,不存在返回nil
可选参数:
EX:以秒为单位设置过期时间
PX:以毫秒为单位设置过期时间
EXAT:设置以秒为单位的UNIX时间戳所对应的时间为过期时间
PXAT:设置以毫秒为单位的时间戳为过期时间
NX:键不存在的时候添加键值对,存在返回nil
XX:键存在的时候设置键值,也就是覆盖,不存在返回nil
GET:返回指定键原本的值,若不存在返回nil
KEEPTTL:保留键之前的生存时间,即在覆盖键值时过期时间还是之前的过期时间提示:set命令使用EX、PX、NX参数,效果等同于SETEX、SETPX、SETNX。
1 |
|
1 |
|
1 |
|
1 |
|
MSET和MGET
M是multi的缩写,表示多个的意思。
**mset key value [key value ...]
**:批量添加多个String类型的键值对
1 |
|
**mget key [key ...]
**:批量获取String类型的value
1 |
|
INCR、INCRBY
increase的缩写,表示自增
**incr key
**:让一个整型的key自增1
1 |
|
**incrby key step
**:指定步长step,让一个整型的key自增step
1 |
|
**incrbyfloat key step
**:让一个浮点类型的数字指定步长自增(浮点类型只能指定步长自增,incrbyfloat也是用整型)
1 |
|
DECR、DECRBY、DECRBYFLOAT
自减,操作和上述自增一样。
SETNX和SETEX
setnx:已存在就不会改变键的值。NX是not exists的缩写。
setex:设定键的过期时间。EX是expire的缩写。
**setnx key value
**:如果key不存在则创建一个String类型的键值对,如果key存在,则不执行。创建成功返回1,失败返回0。
**setex key second
**:创建一个String类型的键值对,并设置过期时间,second为秒数
MSETNX
**msetnx key value [key value ...]
**:批量添加多个String类型的键值对。
当且仅当要创建的所有key都不存在时才创建成功。只要有一个键已存在,则都创建失败。
SETRANGE和GETRANGE
**setrange key offset value
**:从指定位置替换值的内容,offset表示偏移量,如果为1表示从第二个字符开始。value为替换的内容。
**getrange key start end
**:获取key值指定范围的内容,start表示开始索引,end表示结束索引。0到-1表示获取全部。
STRLEN
**strlen key
**:获取key值的长度
1 |
|
APPEND
**append key value
**:在key值后追加内容value
1 |
|
GETSET
**getset key value
**:设置键值对时先获取原先的key值再设置新的key值,等价于set key get
。
key的结构
Redis没有类似MySQL中的Table的概念,我们该如何区分不同类型的key呢?
例如,需要存储用户、商品信息到redis,有一个用户id是1,有一个商品id恰好也是1,此时如果使用id作为key,那就冲突了该怎么办?
我们可以通过给key添加前缀加以区分,不过这个前缀不是随便加的,有一定的规范:
Redis的key允许有多个单词形成层级结构,多个单词之间用’:’隔开,格式如下:
1 |
|
这个格式并非固定,也可以根据自己的需求设计。这样我们就可以把不同类型的数据区分开了,从而避免了key的冲突问题。
例如我们的项目名称叫 heima,有user和product两种不同类型的数据,我们可以这样定义key:
user相关的key:heima:user:1
product相关的key:heima:product:1
如果Value是一个Java对象,例如一个User对象,则可以将对象序列化为JSON字符串后存储:
KEY | VALUE |
---|---|
heima:user:1 | {“id”:1, “name”: “Jack”, “age”: 21} |
heima:product:1 | {“id”:1, “name”: “小米11”, “price”: 4999} |
并且,在Redis的桌面客户端中,还会以相同前缀作为层级结构,让数据看起来层次分明,关系清晰:
二. List(列表)
Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)
它的底层实际是个双端链表,最多可以包含 2^32 - 1 个元素 (4294967295, 每个列表超过40亿个元素)
left、right都可以插入添加;
如果键不存在,创建新的链表;
如果键已存在,新增内容;
如果值全移除,对应的键也就消失了。
- 它的底层实际是个双向链表,对两端的操作性能很高,通过索引下标的操作中间的节点性能会较差。
列表
Redis的List类型是一个单Key多Value的集合,其value值是有序可重复的。
Redis中的List类型与Java中的LinkedList类似,可以看做是一个双向链表结构。既可以支持正向检索和也可以支持反向检索。
如果键不存在,创建新的链表;
如果键已存在,新增内容,可重复;
如果值全移除,对应的键也就消失了。
特征与LinkedList类似:①有序 ②可重复 ③插入和删除速度快 ④查询速度一般
常用来存储一个有序数据,例如朋友圈点赞列表,评论列表等等。
List类型常用命令:
LPUSH和RPUSH
向列表头部或尾部插入元素。返回值为执行命令后列表的长度。当key不存在时则创建key。
**LPUSH key element [element ...]
**:在列表key左边添加一个或多个元素,也就是在列表的头部添加元素。
**RPUSH key element [element ...]
**:在列表key右边添加一个或多个元素,也就是在列表的尾部添加元素。
1 |
|
LPUSHX和RPUSHX
仅当列表存在时入栈,返回值为执行命令后列表的长度。
**LPUSHX key vlaue
**:将value值插入到列表Key的表头,当且仅当 key存在并且是一个列表。当key不存在,执行失败,返回0。
**RPUSHX key value
**:将值 value插入到列表key的表尾,当且仅当 key存在并且是一个列表。当key不存在,执行失败,返回0。
LRANGE
没有RRANGE。
**LRANGE key start stop
**:返回列表 key中指定区间内的元素,区间以偏移量(索引) start
和 stop
指定。
0表示第一个元素,1表示列表第二个元素;-1表示列表最后一个元素,-2表示列表倒数第二个元素,以此类推。
如果start的下标比列表最大的下标end(LLEN list减一)还大,那么Lrange返回一个空列表。
如果stop的下标比end的下标还要大,Redis将stop的值设置为end。
0到-1表示列表的所有元素
。
LPOP和RPOP
弹出列表最左端或最右端的元素。
**LPOP key [count]
**:移除列表最左侧的元素并返回该元素,没有则返回nil,count为移除的个数。
**RPOP key [count]
**:移除列表最右侧的元素并返回该元素,没有则返回nil,count为移除的个数。
BLPOP和BRPOP
B是blocking的缩写,表示阻塞的意思。
与LPOP和RPOP类似,只不过在没有元素时等待指定时间,而不是直接返回nil。
**BLPOP key [key ...] timeout
**:移除列表第一个元素并返回该元素,如果列表没有元素会阻塞队列直到等待超时或发现可弹出元素为止
**BRPOP key [key ...] timeout
**:移除列表最后一个元素并返回该元素,如果列表没有元素会阻塞队列直到等待超时或发现可弹出元素为止
RPOPLPUSH
**RPOPLPUSH source destination
**:将列表source中的尾元素弹出插入到列表destination的头部,并返回该元素。
如果source不存在,返回nil。
如果source和destination相同,则列表中的表尾元素被移动到表头,并返回该元素,这种情况可以视为列表的旋转操作。
Redis的列表经常被用作队列(queue),用于在不同程序之间有序地交换消息(message)。一个客户端通过 LPUSH命令将消息放入队列中,而另一个客户端通过 RPOP或者 BRPOP命令取出队列中等待时间最长的消息。
上面的队列方法是『不安全』的,因为在这个过程中,一个客户端可能在取出一个消息之后崩溃,而未处理完的消息也就因此丢失。
使用RPOPLPUSH命令(或者它的阻塞版本 BRPOPLPUSH )可以解决这个问题:因为它不仅返回一个消息,同时还将这个消息添加到另一个备份列表当中,如果一切正常的话,当一个客户端完成某个消息的处理之后,可以用 LREM 命令将这个消息从备份表删除。
最后,还可以添加一个客户端专门用于监视备份表,它自动地将超过一定处理时限的消息重新放入队列中去(负责处理该消息的客户端可能已经崩溃),这样就不会丢失任何消息了。
LINDEX
**LINDEX key index
**:通过索引获取列表元素。
下标(index)参数 start
和 stop
都以 0
为底,也就是说,以 0
表示列表的第一个元素,以 1
表示列表的第二个元素,以此类推。
你也可以使用负数下标,以 -1
表示列表的最后一个元素, -2
表示列表的倒数第二个元素,以此类推。
如果 index
参数的值不在列表的区间范围内(out of range),返回 nil
。如果 key
不是列表类型,返回一个错误。
LLEN
**LLEN key
**:返回列表key的长度。
如果key不存在,则key被解释为一个空列表,返回0。
如果key不是一个列表类型返回一个错误。
LREM
remove的缩写,移除指定元素。
返回值:被移除元素的数量。不存在的
key
被视作空表(empty list),所以当key
不存在时, LREM命令总是返回 0 。
**LREM key count value
**:根据count的值,移除列表中与参数value相等的元素。
count
的值可以是以下几种:
count > 0
: 从表头开始向表尾搜索,移除与value
相等的元素,数量为count
。count < 0
: 从表尾开始向表头搜索,移除与value
相等的元素,数量为count
的绝对值。count = 0
: 移除表中所有与value
相等的值。
LTRIM
对一个列表进行修剪(trim),让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。
**LTRIM key start stop
**:让列表key只保留start
-stop
区间的元素。成功返回ok,若key不是列表类型返回错误。
下标(index)参数
start
和stop
都以 0 为底,也就是说,以 0 表示列表的第一个元素,以 1 表示列表的第二个元素,以此类推。
也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。
LSET
**LSET key index value
**:将列表key下标为index的元素的值设置为value。操作成功返回ok。
当index参数超出范围,或对一个空列表(key不存在)进行LSET时,返回一个错误。关于更多的下标信息,参考LINDEX。
LINSERT
**LINSERT key BEFORE|AFTER element value
**:将值value插入到列表key中element元素之前或之后。
当
element
不存在列表key
中时,不执行任何操作。当key
不存在时,也不执行任何操作。若key
不是列表类型,返回一个错误。返回值:
如果命令执行成功,返回插入操作完成之后,列表的长度。
如果没有找到element
,返回-1
。
如果key
不存在或为空列表,返回0
。
三. Hash(哈希)
Redis hash 是一个 string 类型的 field(字段) 和 value(值) 的映射表,hash 特别适合用于存储对象。
Redis 中每个 hash 可以存储 2^32 - 1 键值对(40多亿)
哈希表
hash类型,也叫做散列。其value是一个无序字典,类似于java中的HashMap结构。
K-V模式不变,但v又是一个键值对:Map<key,Map<key,value>>
String结构是将对象序列化为JSON字符串后存储,当需要修改对象某个字段时很不方便:
Hash结构可以将对象中的每个字段独立存储,可以针对单个字段做CRUD,下面是两个哈希表:
Hash类型的常用命令:
HSET和HGET
**HSET key field value [field value ...]
**:将hash表key中的域field的值设置为value,支持同时设置多个域-值对。
如果key不存在,一个新的hash表被创建并执行HSET操作。
如果域field不存在,表示新增field-value
(域值对),如果域field已经存在哈希表key中,其旧值将被覆盖。返回值:
如果 field 是哈希表中的一个新建域,并且值设置成功,返回 1 。多个则返回对应的个数。
如果哈希表中域 field 已经存在且旧值已被新值覆盖,返回 0。
**HGET key field
**:根据给定域field返回对应的value值。当key不存在或者field不存在,返回nil。
HMSET和HMGET
**HMSET key field value [field value ...]
**:同时将多个field-value
(域-值对)设置到哈希表key中。
此命令会覆盖哈希表中已存在的域,如果key不存在,一个空的哈希表被创建并执行HMSET操作。
返回值:执行成功返回ok;若key不是hash类型,返回一个错误。
HSET在Redis版本迭代后也支持同时设置多个值到哈希表中,与HMSET操作完全相同,HMSET今后可能被淘汰。
**HMGET key field [field ...]
**:返回哈希表key中一个或多个给定的域值。
如果给定的域不存在于哈希表,那么返回一个
nil
值。key不存在时也返回一个nil
值。key不是Hash类型时报错。
HGETALL
**HGETALL key
**:返回哈希表key中所有的field
和value
。
在返回值里,紧跟着域名后的是域的值,所以返回值的长度是哈希表大小的两倍。
返回值:以列表形式返回哈希表的域和值,若key不存在,返回空列表。若key不是hash类型则报错。
若在Redis客户端这样显示的数据就是列表:
1)”AA”
2)”BB”
3)”CC”
…
HDEL
**HDEL key field [field ...]
**:删除哈希表 key
中的一个或多个指定域,不存在的域将被忽略。
返回值:被成功移除的域的数量,不包括被忽略的域。
HLEN
**HLEN key
**:返回哈希表 key
中域的数量。
返回值:返回哈希表中域的数量,当key不存在时返回0,若key不是hash类型则报错。
HEXISTS
**HEXISTS key field
**:查看哈希表key中,给定域field是否存在。
如果哈希表中存在给定域,返回
1
。
如果哈希表中不存在给定域,或key
不存在,返回0
。
HKEYS和HVALS
**HKEYS key
**:获取哈希表key中所有的field
返回值:返回哈希表中所有field的
数组
,若key不存在返回一个空数组。若key不是hash类型返回错误。
**HVALS key
**:获取哈希表key中所有field对应的value
值。
返回值:返回哈希表中所有field对应的value的
数组
,若key不存在返回一个空数组。若key不是hash类型返回错误。
HINCRBY、HINCRBYFLOAT
**HINCRBY key field increment
**:为哈希表 key
中的域 field
的值加上增量 increment
。只适用整型字符串
**HINCRBYFLOAT key field increment
**:为哈希表 key
中的域 field
加上浮点数增量 increment
。只适用浮点型字符串
增量也可以为负数,相当于对给定域进行减法操作。
如果哈希表
key
不存在,那么会先创建一个哈希表,再创建域field
,最后再执行HINCRBY
或HINCRBYFLOAT
操作。如果域
field
不存在,那么在执行命令前,域的值被初始化为0
,然后后执行HINCRBY
或HINCRBYFLOAT
操作。对一个储存
非整型字符串
的域 field 执行HINCRBY
命令将造成一个错误。对一个储存
非数值型字符串
的域 field 执行HINCRBYFLOAT
命令将造成一个错误。本操作的值被限制在 64 位(bit)有符号数字表示之内。
HSETNX
**HSETNX key field value
**:向哈希表key中添加field-value
,当且仅当域field不存在。
若field已存在,则该操作无效;若key不存在,则创建该哈希表并执行HSETNX操作。
返回值:添加成功,返回1;如果给定域已经存在返回 0 。
四. Set(集合)
Redis 的 Set 是 String 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据,集合对象的编码可以是 intset 或者 hashtable。
Redis 中Set集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。
集合中最大的成员数为 2^32 - 1 (4294967295, 每个集合可存储40多亿个成员)
集合
Redis的Set类型是一个和List一样的单key多value的集合,与List不同的是Set的value是无序且不可重复的。
Redis的set相当于Java语言里面的HashSet,它内部键值对是无序的、唯一的。它的内部实现相当于一个特殊的字典,字典中所有的value都是一个值NULL,可以看做是一个value为null的HashMap。
具备与HashSet类似的特征:
- 无序
- 元素不可重复
- 查找快
- 支持交集、并集、差集等功能
应用场景:
微信抽奖小程序。(SRANDMEMBER)
微信朋友圈共友点赞。(SINTER)
QQ推荐可能认识的人。(SDIFF)
Set类型的常用命令:
SADD
**SADD key member [member ...]
**:将一个或多个 member
元素加入到set集合 key
当中,已经存在于集合的 member
元素将被忽略。
假如
key
不存在,则创建一个只包含member
元素作成员的集合。当
key
不是Set集合类型时,返回一个错误。返回值:被添加到集合中的新元素的数量,不包括被忽略的元素。
SMEMBERS
**SMEMBERS key
**:返回集合key
中所有的成员。
若key不存在,返回空数组;若key不是Set集合,返回错误。
SISMEMBER
S表示Set集合,ISMEMBER表示is member?
SISMEMBER key member:判断 member
元素是否是集合 key
的成员。
如果
member
元素是集合的成员,返回1
。如果
member
元素不是集合的成员,或key
不存在,返回0
。
SCARD
**SCARD key
**:返回集合key中成员的个数。当key不存在时,返回0。若key不是Set集合类型,返回错误。
1 |
|
SREM
**SREM key member [member ...]
**:移除集合key中的一个或多个member元素并返回移除的个数,不存在的member元素会被忽略。
1 |
|
SRANDMEMBER
**SRANDMEMBER key [count]
**:随机返回集合中一个[或多个]元素。仅仅返回随机元素,而不对集合进行任何改动。
SRANDMEMBER命令可选的
count
参数:
- 如果
count
为正数,且小于集合基数,那么命令返回一个包含count
个元素的数组,数组中的元素各不相同。
如果count
大于等于集合基数,那么返回整个集合。- 如果
count
为负数,那么命令返回一个数组,数组中的元素可能会重复出现多次,而数组的长度为count
的绝对值。返回值:
只提供key
参数时,返回一个元素;如果集合为空,返回nil
。
如果提供了count
参数,那么返回一个数组;如果集合为空,返回空数组。
SPOP
SPOP key [count]
:移除并返回集合中的一个[或多个]随机元素。
如果只想获取一个随机元素,但不想该元素从集合中被移除的话,可以使用 SRANDMEMBER命令。
返回值:被移除的随机元素。当
key
不存在或key
是空集时,返回nil
。
SMOVE
**SMOVE source destination member
**:将 member
元素从 source
集合移动到 destination
集合。
SMOVE是原子性操作。
如果
source
集合不存在或不包含指定的member
元素,则 SMOVE 命令不执行任何操作,仅返回0
。当
destination
集合已经包含member
元素时, SMOVE 命令只是简单地将source
集合中的member
元素删除。当
source
或destination
不是集合类型时,返回一个错误。返回值:
如果
member
元素被成功移除,返回1
。如果
member
元素不是source
集合的成员,并且没有任何操作对destination
集合执行,那么返回0
。
1 |
|
集合运算
SDIFF
**SDIFF key key2 ...
**:返回给定集合的差集。
sdiff A B:返回属于集合A但不属于集合B的元素
sdiff B A:返回属于集合B但不属于集合A的元素
SUNION
**SUNION key [key ...]
**:返回给定集合的并集。
比如
sunion A B
表示返回集合A和集合B的所有元素,公共的只取一份。
SINTER
**SINTER key [key ...]
**:返回给定集合的交集。
比如
sinter A B
表示即返回集合A和集合B共有的元素。
SINTERCARD numkeys key [key ...] [LIMIT limit]
:返回给定集合交集的个数。
此命令为redis7新出的命令。
numkeys为key的个数。
LIMIT为限制返回的个数的最大值,比如交集个数有10个,但是LIMIT为5,则返回5。
五. SortedSet(有序集合)
zset(sorted set:有序集合)
Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联一个double类型的分数,redis正是通过分数来为集合中的成员进行从小到大的排序。
zset的成员是唯一的,但分数(score)却可以重复。
zset集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。 集合中最大的成员数为 2^32 - 1
有序集合
SortedSet也叫ZSet。在Set的基础上,每个member前面加个score属性。
Redis的SortedSet是一个可排序的set集合,与Java中的TreeSet有些类似,但底层数据结构却差别很大。
SortedSet中的每一个元素都带有一个score属性,可以基于score属性对元素排序,底层的实现是一个跳表(SkipList)加 hash表。
score的值是一个整型数值或者浮点数值 的数,是可重复的。
SortedSet具备下列特性:
- 可排序
- 元素不重复
- 查询速度快
因为SortedSet的可排序特性,经常被用来实现排行榜这样的功能。比如商品销售排行榜。
Zset类型的常用命令:
ZADD
**ZADD key score member [[score member] [score member] ...]
**:将一个或多个元素及其score
值添加到有序集合key
中。
如果某个
member
已经是有序集的成员,那么更新这个member
的score
值,并通过重新插入这个member
元素,来保证该member
在正确的位置上。
score
是一个用于排序的属性,它的值是整数值或双精度浮点数,score
写在member
的前面。如果
key
不存在,则创建一个空的有序集并执行ZADD
操作。当key
存在但不是有序集类型时,返回一个错误。当然还可以加其他参数比如
NX
、XX
、INCR
等等,对有序集的更多介绍参见 sorted set 。
1 |
|
ZCARD
**ZCARD key
**:返回有序集 key
中成员的个数。当key不存在时返回0,若key不是有序集类型,返回错误。
1 |
|
ZCOUNT
**ZCOUNT key min max
**:返回有序集 key
中, score
值在 min
和 max
之间(默认包括 score
值等于 min
或 max
)的成员的数量。
默认情况下,区间的取值使用闭区间(小于等于或大于等于),也可以通过给参数前增加
(
符号将其改变为开区间。
比如(1 5
表示 1<score<=5,(1 (5
表示 1<score<5。
ZSCORE
**ZSOCRE key member
**:返回有序集 key
中指定成员 member
的 score
值。
如果
member
元素不是有序集key
的成员,或key
不存在,返回nil
。返回值:
member
成员的score
值,以字符串形式表示。
ZRANGE和ZREVRANGE
**ZRANGE key start stop [WITHSCORES]
*:返回有序集合key中指定区间的成员。从小到大排序*
其中成员的位置是按score值从小到大排序,具有相同score的车成员按字典序来排列。区间(下标参数)这里不再赘述。
WITHSCORES
选项,表示让成员和它的score
值一并返回,返回列表以member1,score1, ..., memberN,scoreN
的格式表示。
可能会返回一些更复杂的数据类型,比如数组、元组等。如果需要按score值从大到小排序,可以适用
ZREVRANGE
命令。
**ZREVRANGE key start stop [WITHSCORES]
*:返回有序集合key中指定区间的成员。从大到小排序*
成员的位置是按照
score
值从大到小排序,其余都和ZRANGE
一样。
ZRANGEBYSCORE和ZREVRANGEBYSCORE
**ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
*:返回有序集 key
中所有 score
值介于 min
和 max
之间(包括等于 min
或 max
)的成员。按score值从小到大排序*
默认情况下,区间的取值使用闭区间(小于等于或大于等于),也可以通过给参数前增加
(
符号来使用可选的开区间(小于或大于)。
比如(1 5
表示 1<score<=5,(1 (5
表示 1<score<5。
LIMIT
参数限制返回结果的区间(就像SQL中的SELECT ... LIMIT offset, count
),offset为下标偏移量,count为个数。
WITHSCORES
表示将有序集成员及其score
值一起返回。
**ZREVRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
*:返回有序集 key
中所有 score
值介于 min
和 max
之间(包括等于 min
或 max
)的成员。按score值从大到小排序*,其余参考ZRANGEBYSCORE。
ZRANK和ZREVRANK
**ZRANK key member
*:返回有序集 key
中指定成员 member
的排名。从小到大*
排名按
score
值递增(从小到大)顺序排列。排名以0
为底,也就是说score
值最小的成员排名为0
。使用
ZREVRANK
命令可以获得成员按score
值递减(从大到小)排列的排名。
**ZREVRANK key member
*:返回有序集 key
中指定成员 member
的排名。从大到小*
ZREM
**ZREM key member [member ...]
**:移除有序集key中一个或多个成员,不存在的成员将被忽略。
当key不存在时返回0;当key存在但不是有序集时返回一个错误。
移除成功返回移除成员的数量。
1 |
|
ZINCRBY
**ZINCRBY key increment member
**:为有序集 key
的成员 member
的 score
值加上增量 increment
可以通过传递一个负数值 ,让
score
减去相应的值,比如ZINCRBY key -5 member
,就是让member
的score
值减去5
。返回值:返回
member
成员的新score
值,以字符串形式表示。
当key
不是有序集类型时,返回一个错误。
当key
不存在,或member
不是key
的成员时,ZINCRBY key increment member
等同于ZADD key increment member
。
score
值可以是整数值或双精度浮点数。
ZPOPMAX和ZPOPMIN
**ZPOPMAX key [count]
**:删除并返回有序集key
中score
值最大的一个[或多个]成员。
**ZPOPMIN key [count]
**:删除并返回有序集key
中score
值最小的一个[或多个]成员。
ZMPOP
**ZMPOP numkeys key [key ...] <MIN | MAX> [COUNT count]
**:从所提供的键名列表中的第一个非空排序集中弹出一个[或多个]元素,这些元素是成员分数对。
这个指令就是ZPOPMAX和ZPOPMIN的升级版,可以对多个有序集合进行操作。
集合运算
集合运算参考Set的集合运算,这里不再赘述。
ZDIFF:求差集
ZINTER:求交集
ZUNION:求并集
六. Bitmap(位图)
由0和1状态表现的二进制位的bit数组
位图
用String类型作为底层数据结构实现的一种统计二值状态的数据类型。
位图本质是数组,该数组由多个二进制位组成,其值只能是1或0,默认0,每个二进制位都对应一个偏移量(我们称之为一个索引)。
Bitmap支持的最大位数是2^32位,它可以极大的节约存储空间,使用512M内存就可以存储多达42.9亿的字节信息。
(512*1024*1024*8=2^9*2^10*2^10*2^3=2^32)一个字节占有8位,若在一个bitmap类型的key中,偏移量(索引)为8的位置存入1,前面7位会默认设置为0,那么该key占用两个字节,因为偏移量为8的那一位属于第二个字节了。
==应用== :由于offset值得范围是[0,2^32-1],这个数非常大,可以将用户id和偏移量形成映射关系来存储很多二值数据:
通常先将用户存储到哈希表中,通过field值来标识每一位用户,然后再将field值和偏移量形成映射关系,比如HSET user 1 uid1001 2 uid1002
:1代表uid1001,2代表uid1002SETBIT sign:Monday 1 1
偏移量1的位置值为1,偏移量1对应用户uid1001(1表示已签到,0表示未签到)SETBIT sign:Monday 2 1
偏移量2的位置值为1,偏移量2对应用户uid1002
……SETBIT sign:Monday n 1
再通过BITCOUNT sign:Monday
就很容易获取Monday签到的用户数量了。
Bitmap结构的常用命令:
SETBIT
**SETBIT key offset value
**:设置key的value(字符串)在offset处的bit值。
offset:偏移量,从0开始,最大值2^32-1
返回值:在offset处原来的bit值。
GETBIT
**GETBIT key offset
**:返回key对应的value在offset处的bit值。
当offset超出了字符串长度的时候,超出的部分就被假定为由0比特填充的连续空间。
当key不存在的时候,它就认为是一个空字符串,所以offset总是超出范围,然后value也被认为是由0比特填充的连续空间。
1 |
|
BITCOUNT
**BITCOUNT key [start end [byte|bit]]
**:统计value中比特位为1的个数。
可以指定特定的比特位区间或字节区间,只统计该区间上比特位为1的个数。
byte表示一个字节为一个偏移量,bit表示一个位为一个偏移量。
1 |
|
BITOP
**BITOP operation destkey key [key ...]
**:对一个或多个保存二进制位的字符串key进行位运算,并将结果保存到destkey中。
operation有四种操作:AND、OR、NOT、XOR
BITOP AND destkey srckey1 srckey2 srckey3 ... srckeyN
:对一个或多个 key 求按位与(同一列都为1则为1)BITOP OR destkey srckey1 srckey2 srckey3 ... srckeyN
:对一个或多个 key 求按位或(同一列有一个1即为1)BITOP XOR destkey srckey1 srckey2 srckey3 ... srckeyN
:对一个或多个 key 求按位异或(不同则为1)BITOP NOT destkey srckey
:对给定 key 求按位取反(1变0,0变1)返回值:保存到destkey的字符串的长度(多少字节)
1 |
|
七. HyperLogLog(基数统计)
HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定且是很小的。
在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基 数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。
但是,因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。
基数统计
HyperLogLog是一种概率数据结构,用于计数唯一的事物(技术上这是指估计一个集合的基数)。
(基数就是一个数据集中去除重复数据后总的个数)HyperLogLog的数据类型还是String。在Redis中的HyperLogLog,虽然技术上是不同的数据结构,但被编码为Redis字符串。
在Redis里面每个HyperLogLog键只需要花费12kb内存就可以统计接近2^64个不同元素的基数。
HyperLogLog只会根据输入的元素来计算奇数,不会存储输入的元素本身,所以HyperLogLog不能像集合那样返回输入的元素。
HyperLogLog结构的常用命令:
PFADD
**PFADD key element [element ...]
**:将元素element添加到HyperLogLog结构的key中。
如果 HyperLogLog 的内部被修改了,那么返回 1,否则返回 0 。
如果在调用该命令时仅提供变量名而不指定元素也是可以的,如果这个变量名存在,则不会有任何操作。如果不存在,则会创建一个数据结构(返回1)。
1 |
|
PFCOUNT
**PFCOUNT key [key ...]
**:返回给定HyperLogLog结构的key的基数。
当参数为一个key时,返回存储在HyperLogLog结构体的该key的近似基数,如果该变量不存在,则返回0。
当参数为多个key时,返回这些HyperLogLog并集的近似基数,这个值是将所给定的所有key的HyperLoglog结构合并到一个临时的HyperLogLog结构中计算而得到的。
1 |
|
PFMERGE
**PFMERGE destkey [sourcekey [sourcekey ...]]
**:将多个HyperLogLog合并成一个HyperLogLog。
destkey是合并后的HyperLogLog结构。
这个命令可以用PFCOUNT命令实现。
1 |
|
八. Geospatial(地理空间)
Redis GEO 主要用于存储地理位置信息,并对存储的信息进行操作,包括
添加地理位置的坐标。
获取地理位置的坐标。
计算两个位置之间的距离。
根据用户给定的经纬度坐标来获取指定范围内的地理位置集合
地理空间
Redis地理空间索引可以存储坐标并搜索它们。此数据结构用于在给定半径或包围框内查找附近点。
Geopatial的数据类型是Zset,相当于由之前的
score
变成了longitude
和latitude
,可以使用Zset的命令对其进行操作。
Geospatial结构的常用命令:
GEOADD
GEOADD key [NX | XX] [CH] longitude latitude member [longitude latitude member ...]
将指定的地理空间项(经度、纬度、名称)添加到地理空间结构的key中。
数据以有序集的形式存储到键中,这样就可以使用GEOSEARCH命令查询项。
规定如下:
- 有效的经度从-180度到180度。
- 有效的纬度从-85.05112878度到85.05112878度。
当坐标位置超出上述指定范围时,该命令将会返回一个错误。
1 |
|
注意:使用–raw启动客户端后,返回数据的类型以及编号不会显示了
GEOPOS
**GEOPOS key member [member ...]
**:从给定的key里返回所有指定member的位置(经度和纬度),不存在的member返回nil。
GEOPOS 命令返回一个数组, 数组中的每个项都由两个元素组成: 第一个元素为给定位置元素的经度, 而第二个元素则为给定位置元素的纬度。给定的位置元素不存在时, 对应的数组项为空值。
1 |
|
GEOHASH
**GEOHASH key member [member ...]
**:获取一个或多个member
的geohash值。
通常使用表示位置的元素使用不同的技术,使用Geohash位置52点整数编码。
由于编码和解码过程中所使用的初始最小和最大坐标不同,编码的编码也不同于标准。此命令返回一个标准的Geohash。
1 |
|
GEODIST
**GEODIST key member1 member2 [M | KM | FT | MI]
**:返回两个给定member
之间的距离。
如果两个位置之间的其中一个不存在, 那么命令返回空值。
- m 表示单位为米。
- km 表示单位为千米。
- mi 表示单位为英里。
- ft 表示单位为英尺。
如果用户没有显式地指定单位参数, 那么
GEODIST
默认使用M作为单位。
1 |
|
GEORADIUS
GEORADIUS key longitude latitude radius <M | KM | FT | MI> [WITHCOORD] [WITHDIST] [WITHHASH]
[COUNT count [ANY]] [ASC | DESC] [STORE key] [STOREDIST key]
以给定的经纬度为中心, 返回key包含的位置元素当中, 与中心的距离不超过给定最大距离的所有位置元素。
radius:半径
WITHDIST:在返回位置元素的同时, 将位置元素与中心之间的距离也一并返回。 距离的单位和用户给定的范围单位保持一致。
WITHCOORD: 将位置元素的经度和维度也一并返回。
WITHHASH:将geohash值一并返回。
COUNT :限定返回的记录数。
ASC:由近到远返回(升序)
DESC:由远到近返回(降序)
1 |
|
GEORADIUSBYMEMBER
GEORADIUSBYMEMBER key member radius <M | KM | FT | MI> [WITHCOORD] [WITHDIST] [WITHHASH]
[COUNT count [ANY]] [ASC | DESC] [STORE key] [STOREDIST key]
以给定的位置元素为中心点,找出位于指定范围内的元素。其他和GEORADIUS命令一样。
1 |
|
九. Stream(流)
流
Redis流是一种数据结构(Stream类型),它的作用类似于只能追加的日志。您可以使用流来实时记录和同时聚合事件。
Redis流用例示例包括:
事件来源(例如,跟踪用户操作、点击等)
传感器监测(例如,来自现场设备的读数)
通知(例如,在单独的流中存储每个用户通知的记录)
Redis为每个流消息生成一个唯一的ID,可以使用这些id检索它们关联的消息,或者读取和处理流中的所有后续消息。
四种和ID有关的特殊符号:
-
和+
:当前流中最小ID和最大ID$
:表示大于当前流中最大的id,用于新添加的消息>
:用于XREANGROUP命令,表示迄今没有发送给组中使用者的信息,会更新消费者组的最后ID*
:用于XADD命令中,表示让系统自动生成ID
Stream流就是Redis版的MQ消息中间件+阻塞队列,它能实现消息队列,它支持消息的持久化、支持自动生成全局唯一ID、支持ack确认消息的模式、支持消费组模式等,让消息队列更加的稳定和可靠。
Message Content:消息内容
Consumer group:消费组,通过XGROUP CREATE 命令创建,同一个消费组可以有多个消费者
Last_delivered_id:游标,每个消费组会有个游标 last_delivered_id,任意一消费者读取了消息都会使游标 last_delivered_id 往前移动。
Consumer:消费者,消费组中的消费者
Pending_ids:消费者会有一个状态变量,用于记录被当前消费已读取但未ack的消息Id,如果客户端没有ack,这个变量里面的消息ID会越来越多,一旦某个消息被ack它就开始减少。这个pending_ids变量在Redis官方被称之为 PEL(Pending Entries List),记录了当前已经被客户端读取的消息,但是还没有 ack (Acknowledge character:确认字符),它用来确保客户端至少消费了消息一次,而不会在网络传输的中途丢失了没处理
Stream类型的常用命令:
XADD
XADD key [NOMKSTREAM] [<MAXLEN | MINID> [= | ~] threshold [LIMIT count]] <* | id> field value [field value ...]
将消息追加到指定流
key
的末尾,添加的消息ID要比上个消息的ID大。如果key不存在,将自动创建流key然后执行XADD操作。ID用于标识给定消息,如果指定的ID参数是字符
*
,XADD
命令会自动生成一个唯一的ID。ID是由时间戳-序列号两部分组成,当自动生成ID时,第一部分是生成ID的Redis实例的毫秒格式的Unix时间。 第二部分是一个序列号,用来区分同一毫秒内生成的ID的。序列号是64位长度(18446744073709551615),理论上在同一毫秒内生成的数据量无法到达这个级别,因此不用担心序列号会不够用。该命令返回添加的消息的ID。如果ID参数传的是
*
,那么ID是自动生成的, 否则,命令仅返回用户在插入期间指定的相同的ID。通常使用命令
XADD ID filed value [field value ...]
,其他的花里胡哨的参数了解即可。
1 |
|
XRANGE
**XRANGE key start end [COUNT count]
**:返回给定id范围内流key的消息。
id范围由[start,end]指定。特殊ID:
-
表示流中最小的消息id,+
表示流中最大的消息id。返回的消息由id从小到大排序。
1 |
|
XREVRANGE
**XREVRANGE key end start [COUNT count]
**:返回给定id范围内流key的消息。
在
XREVRANGE
中,要先指定结束ID,再指定开始ID,返回消息的顺序是根据id从大到小排序。其余和XRANGE一样。
1 |
|
XDEL
**XDEL key id [id ...]
**:从流key中删除指定id(消息)。
1 |
|
XLEN
**XLEN mystream
**:返回流key中消息的条数。
1 |
|
XTRIM
**XTRIM key <MAXLEN | MINID> [= | ~] threshold [LIMIT count]
**:将流消息裁剪为指定数量的消息。
MAXLEN:表示允许最大的消息长度(个数),超过此数量会优先删除id较小的消息。
MINID:表示允许最小的id,比此id还小的消息会被删除。
返回值:删除消息的数量。
1 |
|
XREAD
XREAD [COUNT count] [BLOCK milliseconds] STREAMS key [key ...] id [id ...]
从一个或者多个流中读取数据,仅返回id大于对应流中最大id的消息(也就是新添加的消息)。
count:最多读取多少条
block:是否以阻塞的方式读取,如果开启且milliseconds设为0,表示永远阻塞直到读取到消息。
id:表示读取ID大于指定id的消息。
特殊ID:符号
$
。表示以当前Stream已经存储的最大的ID作为最后一个ID,当前Stream中不存在大于当前最大ID的消息,因此此时返回nil。一般用于阻塞队列获取新消息。
1 |
|
消费组相关指令
XGROUP
**XGROUP CREATE key group <id | $>
**:创建消费者组。
最后一个参数是要考虑已传递的流中最后一项的ID。
$表示从Stream尾部开始消费,在这种情况下,从该消费者组获取数据的消费者只能看到到达流的新元素。
0表示从Stream头部开始消费,消费者组可以获取整个流的历史记录。
创建消费者组的时候必须指定 ID, ID 为 0 表示从头开始消费,为 $ 表示只消费新的消息。
1 |
|
**XGROUP CREATECONSUMER key group consumer
**:创建消费者。
1 |
|
**XGROUP DESTORY key group
**:删除流key中指定的消费组。
1 |
|
**XGROUP DELCONSUMER key group consumer
**:删除流key中消费组group的指定消费者。
1 |
|
XREADGROUP
XREADGROUP GROUP group consumer [COUNT count] [BLOCK milliseconds] [NOACK] STREAMS key [key ...] id [id ...]
读取消费者组中的消息。
消费者不存在则自动创建该消费者。
特殊ID:
>
表示从第一条未被消费的消息开始读取。
1 |
|
XPENDING
**XPENDING key group
**:返回待处理消息相关信息。(读取到的消息没有经过XACK确认即为待处理消息)
返回一组数据,包括消费组待处理消息的数量、所有消费者读取的消息最小id、所有消费者所读取id的最大值、每个消费者待处理消息的数量。
1 |
|
**XPENDING key group start end count consumer
**:查看指定消费者具体读取了哪些数据
1 |
|
XACK
**XACK key group id [id ...]
**:向消息队列确认id对应的消息已处理完成,XACK会从待处理消息列表中删除该消息。
返回值:该命令返回成功确认的消息数。
1 |
|
XINFO
**XINFO stream key
**:获取流key的详细信息。
1 |
|
**XINFO GROUPS key
**:获取流key中消费组信息
1 |
|
**XINFO CONSUMERS key group
**:获取流key中消费组group中消费者信息
1 |
|
十. Bitfield(位域)
通过bitfield命令可以一次性操作多个比特位域(指的是连续的多个比特位),它会执行一系列操作并返回一个响应数组,这个数组中的元素对应参数列表中的相应操作的执行结果。
说白了就是通过bitfield命令我们可以一次性对多个比特位域进行操作。
位域
Bitfield结构的底层也是String类型。
Redis位字段允许设置、递增和获取任意位长度的整数值。例如可以对从无符号1位整数到有符号63位整数的任何数字进行操作。
这些值使用二进制编码的Redis字符串存储。位字段支持原子读、写和递增操作,这使它们成为管理计数器和类似数值的好选择。
例如 hello 等价于 0110100001100101011011000110110001101111,每八位对应一个字母,也对应一个十进制值。可以修改每一位的数字从而改变对应的数值从而改变对应的字母。
Bitfield结构的常用命令:
BITFIELD
BITFIELD key [GET type offset] [SET type offset value] [INCRBY type offset increment]
[OVERFLOW WRAP|SAT|FAIL]
此命令会把Redis字符串当作位数组,并能对变长位宽和任意未字节对齐的指定整型位域进行寻址。
下面是已支持的命令列表:
GET <type> <offset>
:返回指定的位域的数值。SET <type> <offset> <value>
: 设置指定位域的数值并返回它的原值。INCRBY <type> <offset> <increment>
: 自增或自减(如果increment为负数)指定位域的值并返回它的新值。type表示多少位的有符号还是无符号整型。有符号整型需在位数前加
i
,无符号在位数前加u
。例如,u8
是一个8位的无符号整型,i16
是一个16位的有符号整型。offset表示偏移量,比如i4表示以4个比特位为一个偏移量。还有一个命令通过设置溢出行为来改变调用
INCRBY
指令的后序操作:OVERFLOW [WRAP|SAT|FAIL]
wrap:使用回环方式处理有符号整数和无符号整数的溢出情况。
sat:使用饱和计算方式处理溢出,下溢计算的结果为最小的整数值,上溢计算的结果为最大的整数值。
fail:命令将拒绝执行那些会导致上溢或者下溢情况出现的计算,并向用户返回空值表示计算未被执行。有符号整型最大支持64位,而无符号整型最大支持63位。对无符号整型的限制,是由于当前Redis协议不能在响应消息中返回64位无符号整数。
字母 | 数值 | 二进制(高位->低位) |
---|---|---|
h | 104 | 0110 1000 |
e | 101 | 0110 0101 |
l | 108 | 0110 1100 |
l | 108 | 0110 1100 |
o | 111 | 0110 1111 |
x | 120 | 0111 1000 |
- GET和SET选项
1 |
|
- INCRBY选项
1 |
|
- OVERFLOW选项
1 |
|