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 | |