当前位置: 首页 > news >正文

【Redis学习】Redis常用数据类型的万字详解

Redis学习笔记:

https://blog.csdn.net/2301_80220607/category_13051025.html?spm=1001.2014.3001.5482

前言:

上一篇已经讲解了Redis中String字符串类型的许多指令的使用,Redis中这些数据类型的相关指令都是十分相似的,今天我们将除了String以外的剩下的几个Redis常用数据类型及其相关知识点讲解一下

目录

一、Hash(哈希)

1. 命令

1.1 HSET

1.2 HGET

1.3 HEXISTS

1.4 HDEL

1.5 HKEYS

1.6 HVALS

1.7 HGETALL

1.8 HMGET

1.9 HLEN

1.10 HSETNX

1.11 HINCRBY

1.12 HINCRBYFLOAT

2. 命令小结

3.内部编码

二、List(列表)

1. 命令

1.1 LPUSH

1.2 LPUSHX

1.3 RPUSH

1.4 RPUSHX

1.5 LRANGE

1.6 LPOP

1.7 RPOP

1.8 LINDEX

1.9 LINSERT

1.10 LLEN

2. 阻塞版本命令

2.1 BLPOP

2.2 BRPOP

3. 内部编码

三、Set(集合)

1. 普通命令

1.1 SADD

1.2 SMEMBERS

1.3 SISMEMBER

1.4 SCARD

1.5 SPOP

1.6 SMOVE

1.7 SREM

2. 集合间操作

2.1 SINTER

2.2 SINTERSTORE

2.3 SUNION

2.4 SUNIONSTORE

2.5 SDIFF

2.6 SDIFFSTORE

四、Zset(有序集合)

1. 普通命令

1.1 ZADD

1.2 ZCARD

1.3 ZCOUNT

1.4 ZRANGE

1.5 ZREVRANGE

1.6 ZRANGEBYSCORE

1.7 ZPOPMAX

1.8 ZPOPMIN

1.9 BZPOPMIN

1.10 ZRANK

1.11 ZSCORE

1.12 ZREM

1.13 ZREMRANGEBYRANK

1.14 ZREMRANGEBYSCORE

1.15 ZINCRBY

2. 集合间操作

2.1 ZINTERSTORE

2.2 ZUNIONSTORE

3. 内部编码

五、总结


一、Hash(哈希)

几乎所有的主流编程语言都支持哈希结构,在不同的编程语言中它可能有不同的叫法:哈希、字典序、映射......我们的Redis也支持哈希这种数据类型,一个有意思的点是:Redis本身的整体数据结构就是以key-value的哈希的结构存在的,这就相当于是哈希中嵌套哈希:key-(key-value),非常有意思,为了避免混淆,我们可以把第二个key改一下:key-(field-value)

1. 命令

1.1 HSET

设置哈希中指定的字段(field)的值(value)

HSET key field value [field value ...]
  • 时间复杂度:插⼊⼀组 field 为 O(1), 插⼊ N 组 field 为 O(N)
  • 返回值:添加的字段的个数。

示例:

127.0.0.1:6379> hset myhash field "hello"
(integer) 1
127.0.0.1:6379> hget myhash field
"hello"

1.2 HGET

获取hash中指定字段的值

HGET key field
  • 时间复杂度:O(1)
  • 返回值:字段对应的值或者 nil。
示例:
127.0.0.1:6379> hset myhash field "hello"
(integer) 1
127.0.0.1:6379> hget myhash field
"hello"
127.0.0.1:6379> hget myhash field2
(nil)

1.3 HEXISTS

判断hash中是否有指定的字段

HEXISTS key field
  • 时间复杂度:O(1)
  • 返回值:1 表⽰存在,0 表⽰不存在。
示例:
127.0.0.1:6379> hset myhash field1 hello
(integer) 1
127.0.0.1:6379> hexists myhash field1
(integer) 1
127.0.0.1:6379> hexists myhash field2
(integer) 0

1.4 HDEL

删除hash中指定的字段

HDEL key field [field ...]
  • 时间复杂度:删除⼀个元素为 O(1). 删除 N 个元素为 O(N).
  • 返回值:本次操作删除的字段个数。
示例:
127.0.0.1:6379> hdel myhash field
(integer) 1
127.0.0.1:6379> hdel myhash field1 field2
(integer) 1

1.5 HKEYS

获取hash中的所有字段

HKEYS key
  • 时间复杂度:O(N), N 为 field 的个数.
  • 返回值:字段列表。
示例:
127.0.0.1:6379> hset myhash field1 hello
(integer) 1
127.0.0.1:6379> hset myhash field2 world
(integer) 1
127.0.0.1:6379> hkeys myhash
1) "field1"
2) "field2"

1.6 HVALS

获取哈希中的所有值

HVALS key
  • 时间复杂度:O(N), N 为 field 的个数.
  • 返回值:所有的值。
示例:
127.0.0.1:6379> hset myhash field1 hello
(integer) 1
127.0.0.1:6379> hset myhash field2 world
(integer) 1
127.0.0.1:6379> hvals myhash
1) "hello"
2) "world"

1.7 HGETALL

获取hash中所有字段以及对应的值

HGETALL key
  • 时间复杂度:O(N), N 为 field 的个数.
  • 返回值:字段和对应的值。
示例:
127.0.0.1:6379> hset myhash field1 hello
(integer) 1
127.0.0.1:6379> hset myhash field2 world
(integer) 1
127.0.0.1:6379> hgetall myhash
1) "field1"
2) "hello"
3) "field2"
4) "world"

1.8 HMGET

一次性获取hash中多个字段的值

HMGET key field [field ...]
  • 时间复杂度:只查询⼀个元素为 O(1), 查询多个元素为 O(N), N 为查询元素个数.
  • 返回值:字段对应的值或者 nil。
示例:
127.0.0.1:6379> hset myhash field1 hello
(integer) 1
127.0.0.1:6379> hset myhash field2 world
(integer) 1
127.0.0.1:6379> hmget myhash field1 field2 nofield
1) "hello"
2) "world"
3) (nil)

注意:在使用上面的HGETALL时,如果hash中元素过多,可能会造成阻塞Redis的情况,如非必要尽量不要选择查看所有的元素,而是通过HMGET来获取指定的元素,如果一定要获取全部的元素时,可以采用我们下面将要讲的HSCAN的分批次进行获取

1.9 HLEN

获取hash中所有字段的个数

HLEN key
  • 时间复杂度:O(1)
  • 返回值:字段个数。
示例:
127.0.0.1:6379> hset myhash field1 hello
(integer) 1
127.0.0.1:6379> hset myhash field2 world
(integer) 1
127.0.0.1:6379> hlen myhash
(integer) 2

1.10 HSETNX

在字段不存在的情况下,设置字段以及对应的值

HSETNX key field value
  • 时间复杂度:O(1)
  • 返回值:1 表⽰设置成功,0 表⽰失败。
示例:
127.0.0.1:6379> hsetnx myhash field1 hello
(integer) 1
127.0.0.1:6379> hsetnx myhash field1 world
(integer) 0
127.0.0.1:6379> hget myhash field1
"hello"

1.11 HINCRBY

将hash中指定字段的数值添加上指定的值

HINCRBY key field increment
  • 时间复杂度:O(1)
  • 返回值:该字段变化之后的值。
示例:
127.0.0.1:6379> hset myhash field 1
(integer) 1
127.0.0.1:6379> hincrby myhash field 10
(integer) 11
127.0.0.1:6379> hincrby myhash field -10

1.12 HINCRBYFLOAT

HINCRBY的FLOAT版本

HINCRBYFLOAT key field increment
  • 时间复杂度:O(1)
  • 返回值:该字段变化之后的值

2. 命令小结

命令
执⾏效果
时间复杂度
hset key field value
设置值
O(1)
hget key field
获取值
O(1)
hdel key field [field ...]
删除 field
O(k), k 是 field
个数
hlen key
计算 field 个数
O(1)
hgetall key
获取所有的 field-value
O(k), k 是 field
个数
hmget field [field ...]
批量获取 field-value
O(k), k 是 field
个数
hmset field value [field
value ...
批量设置 field-value
O(k), k 是 field
个数
hexists key field
判断 field 是否存在
O(1)
hkeys key
获取所有的 field
O(k), k 是 field
个数
hvals key
获取所有的 value
O(k), k 是 field
个数
hsetnx key field value
设置值,但必须在 field 不存在时才能设置成功
O(1)
hincrby key field n
对应 field-value +n
O(1)
hincrbyfloat key field n
对应 field-value +n
O(1)
hstrlen key field
计算 value 的字符串⻓度
O(1)

3.内部编码

  • ziplist(压缩列表):当哈希类型元素个数⼩于 hash-max-ziplist-entries 配置(默认 512 个)、同时所有值都⼩于 hash-max-ziplist-value 配置(默认 64 字节)时,Redis 会使⽤ ziplist 作为哈希的内部实现,ziplist 使⽤更加紧凑的结构实现多个元素的连续存储,所以在节省内存⽅⾯⽐hashtable 更加优秀。
  • hashtable(哈希表):当哈希类型⽆法满⾜ ziplist 的条件时,Redis 会使⽤ hashtable 作为哈希的内部实现,因为此时 ziplist 的读写效率会下降,⽽ hashtable 的读写时间复杂度为 O(1)。

下面来看一下哈希内部的编码,以及响应类型的变换:

当field个数比较少,且内部的值不是很大时,内部编码为ziplist:

127.0.0.1:6379> hmset myhash f1 v1 f2 v2
OK
127.0.0.1:6379> object encoding myhash
"ziplist"

当有value大于64字节时,内部编码会转变为hashtable:

127.0.0.1:6379> hmset myhash f3 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
OK
127.0.0.1:6379> object encoding myhash
"hashtable"

当field个数超过512个时,内部编码也会转化为hashtable:

127.0.0.1:6379> hmset hashkey f1 v1 h2 v2 f3 v3 ... 省略 ... f513 v513
OK
127.0.0.1:6379> object encoding hashkey
"hashtable"

二、List(列表)

列表类型是用来存储多个字符串,如图,a、b、c、d、e五个元素从左到右组成一个有序的列表,列表中每个字符串被称为一个元素,,一个列表最多有2^32-1个元素。在Redis中,列表可以进行两端插入取出,获取指定范围内的元素,获取指定下标的元素等操作,总之列表是Redis中一种十分好用的数据机构,在很多场景下都能够得到使用

1. 命令

1.1 LPUSH

将一个或多个元素头插到列表中

LPUSH key element [element ...]
  • 时间复杂度:只插⼊⼀个元素为 O(1), 插⼊多个元素为 O(N), N 为插⼊元素个数.
  • 返回值:插⼊后 list 的⻓度。

示例:

127.0.0.1:6379> lpush mylist hello
(integer) 1
127.0.0.1:6379> lpush mylist world
(integer) 2
127.0.0.1:6379> lrange mylist 0 -1
1) "world"
2) "hello"

1.2 LPUSHX

当key存在时,将一个或多个元素头插到列表中

LPUSHX key element [element ...]
  • 时间复杂度:只插⼊⼀个元素为 O(1), 插⼊多个元素为 O(N), N 为插⼊元素个数.
  • 返回值:插⼊后 list 的⻓度。
示例:
127.0.0.1:6379> lpush mylist hello
(integer) 1
127.0.0.1:6379> lpushx mylist world
(integer) 2
127.0.0.1:6379> lrange mylist 0 -1
1) "world"
2) "hello"
127.0.0.1:6379> lpushx mylist2 hello
(integer) 0
127.0.0.1:6379> lrange mylist2 0 -1

1.3 RPUSH

将一个或多个元素尾插到列表中

RPUSH key element [element ...]
  • 时间复杂度:只插⼊⼀个元素为 O(1), 插⼊多个元素为 O(N), N 为插⼊元素个数.
  • 返回值:插⼊后 list 的⻓度。
示例:
127.0.0.1:6379> rpush mylist hello
(integer) 1
127.0.0.1:6379> rpush mylist world
(integer) 2
127.0.0.1:6379> lrange mylist 0 -1
1) "hello"
2) "world"

1.4 RPUSHX

当key存在的时候,将一个或多个元素尾插到列表中

RPUSHX key element [element ...]
  • 时间复杂度:只插⼊⼀个元素为 O(1), 插⼊多个元素为 O(N), N 为插⼊元素个数.
  • 返回值:插⼊后 list 的⻓度。

示例:

127.0.0.1:6379> rpush mylist hello
(integer) 1
127.0.0.1:6379> rpushx mylist world
(integer) 2
127.0.0.1:6379> lrange mylist 0 -1
1) "hello"
2) "world"
127.0.0.1:6379> rpushx mylist2 hello
(integer) 0
127.0.0.1:6379> lrange mylist2 0 -1
(empty list or set)

1.5 LRANGE

获取从start到end之间的所有元素,左闭右闭

LRANGE key start stop
  • 时间复杂度:O(N)
  • 返回值:指定区间的元素。
示例:
127.0.0.1:6379> rpush mylist hello
(integer) 1
127.0.0.1:6379> rpush mylist world
(integer) 2
127.0.0.1:6379> lrange mylist 0 -1
1) "hello"
2) "world"

1.6 LPOP

头删

LPOP key
  • 时间复杂度:O(1)
  • 返回值:取出的元素或者 nil。
示例:
127.0.0.1:6379> lrange mylist 0 -1
1) "hello"
2) "world"
127.0.0.1:6379> lpop mylist
"hello"
127.0.0.1:6379> lrange mylist 0 -1
1) "world"

1.7 RPOP

尾删

RPOP key
  • 时间复杂度:O(1)
  • 返回值:取出的元素或者 nil。
示例:
127.0.0.1:6379> lrange mylist 0 -1
1) "hello"
2) "world"
127.0.0.1:6379> rpop mylist
"world"
127.0.0.1:6379> lrange mylist 0 -1

1.8 LINDEX

获取从左数第index位置的元素

LINDEX key index
  • 时间复杂度:O(N)
  • 返回值:取出的元素或者 nil。
示例:
127.0.0.1:6379> lrange mylist 0 -1
1) "hello"
2) "world"
127.0.0.1:6379> lindex mylist 0
"hello"
127.0.0.1:6379> lindex mylist -1
"world"
127.0.0.1:6379> lindex mylist 2

1.9 LINSERT

在特定位置插入元素

LINSERT key <BEFORE | AFTER> pivot element
  • 时间复杂度:O(N)
  • 返回值:插⼊后的 list ⻓度。
示例:
127.0.0.1:6379> lrange mylist 0 -1
1) "hello"
2) "world"
127.0.0.1:6379> linsert mylist before world one
(integer) 3
127.0.0.1:6379> linsert mylist after world two
(integer) 4
127.0.0.1:6379> lrange mylist 0 -1
1) "hello"
2) "one"
3) "world"
4) "two"

1.10 LLEN

获取列表长度

LLEN key
  • 时间复杂度:O(1)
  • 返回值:list 的⻓度。
示例:
127.0.0.1:6379> lrange mylist 0 -1
1) "hello"
2) "one"
3) "world"
4) "two"
127.0.0.1:6379> llen mylist
(integer) 4

2. 阻塞版本命令

blpop和brpop是lpop和rpop的阻塞版本。两者用法很相似,但也有些不同之处:

  • 在列表中有元素的情况下,阻塞和⾮阻塞表现是⼀致的。但如果列表中没有元素,⾮阻塞版本会理 解返回 nil,但阻塞版本会根据 timeout,阻塞⼀段时间,期间 Redis 可以执⾏其他命令,但要求执⾏该命令的客⼾端会表现为阻塞状态
  • 命令中如果设置了多个键,那么会从左向右进⾏遍历键,⼀旦有⼀个键对应的列表中可以弹出元素,命令⽴即返回
  • 如果多个客⼾端同时多⼀个键执⾏ pop,则最先执⾏命令的客⼾端会得到弹出的元素

2.1 BLPOP

LPOP的阻塞版本

BLPOP key [key ...] timeout
  • 时间复杂度:O(1)
  • 返回值:取出的元素或者 nil。

我们看这个命令的语法,它与LPOP主要有两处不同,一是它能同时监视多个key,二是它需要设置一个超时时间,当我们设置一个超时时间后,比如5s,那么在5s内,我们所监视的key里面哪个最先有值我们就头删掉,当头删成功或者超时时,命令就会被结束掉

我们开启两个redis客户端来测试一下,其中一个redis客户端监视多个里面为空的key,另一个客户端向其中一个空值key里面插入一个数据,然后观察命令的执行情况:

当未插入时:

如图,当我们监视的key在指定时间内一直为空时,超时后就会返回空,如果在这个时间内插入数据就会返回插入的值

当插入时:

2.2 BRPOP

RPOP的阻塞版本

BRPOP key [key ...] timeout
  • 时间复杂度:O(1)
  • 返回值:取出的元素或者 nil。

用法方面跟上面的BLPOP同理,这里就不赘述了

3. 内部编码

列表类型的内部编码有两种:

  • ziplist(压缩列表):当列表的元素个数⼩于 list-max-ziplist-entries 配置(默认 512 个),同时列表中每个元素的⻓度都⼩于 list-max-ziplist-value 配置(默认 64 字节)时,Redis 会选⽤
    ziplist 来作为列表的内部编码实现来减少内存消耗。
  • linkedlist(链表):当列表类型⽆法满⾜ ziplist 的条件时,Redis 会使⽤ linkedlist 作为列表的内部实现。

当元素个数较少,且没有大元素时,内部编码为ziplist:

127.0.0.1:6379> rpush listkey e1 e2 e3
OK
127.0.0.1:6379> object encoding listkey
"ziplist"

当元素个数超过512时,内部编码为linkedlist:

127.0.0.1:6379> rpush listkey e1 e2 e3 ... 省略 e512 e513
OK
127.0.0.1:6379> object encoding listkey
"linkedlist"

当某个元素长度超过64字节时,内部编码为linkedlist:

127.0.0.1:6379> rpush listkey "one string is bigger than 64 bytes ... 省略 ..."
OK
127.0.0.1:6379> object encoding listkey
"linkedlist"

三、Set(集合)

集合也是保存多个字符串的类型,但是与列表不同的是,集合内部的元素是无序的,且不能重复,一个集合中最多可以有2^32-1个元素。Redis除了支持集合内部的增删查改,还支持集合间的求交集、并集和差集

1. 普通命令

1.1 SADD

将一个或多个元素添加到set中(不能重复)

SADD key member [member ...]
  • 时间复杂度:O(1)
  • 返回值:本次添加成功的元素个数。
示例:
127.0.0.1:6379> sadd myset "hello" "world" "world"
(integer) 2
127.0.0.1:6379> smembers myset
1) "world"
2) "hello"

1.2 SMEMBERS

获取一个列表中的所有元素(无序的)

SMEMBERS key
  • 时间复杂度:O(N)
  • 返回值:所有元素的列表。
示例:
127.0.0.1:6379> sadd myset "hello" "world" "world"
(integer) 2
127.0.0.1:6379> smembers myset
1) "world"
2) "hello"

1.3 SISMEMBER

判断一个元素在不在set中

SISMEMBER key member
  • 时间复杂度:O(1)
  • 返回值:1 表⽰元素在 set 中。0 表⽰元素不在 set 中或者 key 不存在。
示例:
127.0.0.1:6379> sadd myset one
(integer) 1
127.0.0.1:6379> sismember myset one
(integer) 1
127.0.0.1:6379> sismember myset two
(integer) 0

1.4 SCARD

获取一个set中的元素个数

SCARD key
  • 时间复杂度:O(1)
  • 返回值:set 内的元素个数。
示例:
127.0.0.1:6379> sadd myset one
(integer) 1
127.0.0.1:6379> scard myset
(integer) 1

1.5 SPOP

从set中随机删除指定个数的元素。

SPOP key [count]
  • 时间复杂度:O(N), n 是 count
  • 返回值:取出的元素。
示例:
127.0.0.1:6379> sadd myset one two three
(integer) 3
127.0.0.1:6379> smembers myset
1) "two"
2) "one"
3) "three"
127.0.0.1:6379> spop myset 1
1) "three"
127.0.0.1:6379> smembers myset
1) "two"
2) "one"

1.6 SMOVE

将一个元素从源set转入目标set

SMOVE source destination member
  • 时间复杂度:O(1)
  • 返回值:1 表⽰移动成功,0 表⽰失败。
示例:
127.0.0.1:6379> smembers myset
1) "two"
2) "one"
127.0.0.1:6379> smove myset myset2 one
(integer) 1
127.0.0.1:6379> smembers myset
1) "two"
127.0.0.1:6379> smembers myset2
1) "one"

1.7 SREM

将指定元素从set中删除

SREM key member [member ...]
  • 时间复杂度:O(N), N 是要删除的元素个数.
  • 返回值:本次操作删除的元素个数。
示例:
127.0.0.1:6379> smembers myset
1) "one"
2) "two"
127.0.0.1:6379> srem myset one two three
(integer) 2
127.0.0.1:6379> smembers myset
(empty list or set)

2. 集合间操作

集合间操作主要是指求交集、并集和差集

2.1 SINTER

获取给定set的交集中的元素

SINTER key [key ...]
时间复杂度:O(N * M), N 是最⼩的集合元素个数. M 是最⼤的集合元素个数.
返回值:交集的元素。
示例:
127.0.0.1:6379> sadd myset1 a b c d e f
(integer) 6
127.0.0.1:6379> sadd myset2 a c f h i
(integer) 5
127.0.0.1:6379> sinter myset1 myset2
1) "a"
2) "f"
3) "c"

2.2 SINTERSTORE

获取给定的两个set的交集并将结果保存到给定的set中

SINTERSTORE destination key [key ...]
  • 时间复杂度:O(N * M), N 是最⼩的集合元素个数. M 是最⼤的集合元素个数.
  • 返回值:交集的元素个数。
示例:
127.0.0.1:6379> sadd myset1 a b c d e f
(integer) 6
127.0.0.1:6379> sadd myset2 a c f h i
(integer) 5
127.0.0.1:6379> sinter myset1 myset2
1) "a"
2) "f"
3) "c"
127.0.0.1:6379> sinterstore myret myset1 myset2
(integer) 3
127.0.0.1:6379> smembers myret
1) "a"
2) "f"
3) "c"

2.3 SUNION

获取给定set并集中的元素

SUNION key [key ...]
  • 时间复杂度:O(N), N 给定的所有集合的总的元素个数.
  • 返回值:并集的元素。
示例:
127.0.0.1:6379> sadd myset1 a b c d e f
(integer) 6
127.0.0.1:6379> sadd myset2 a c f h i
(integer) 5
127.0.0.1:6379> sunion myset1 myset2
1) "d"
2) "c"
3) "a"
4) "i"
5) "h"
6) "b"
7) "f"
8) "e"

2.4 SUNIONSTORE

获取给定set并集中的元素并保存到目标的set中

SUNIONSTORE destination key [key ...]
  • 时间复杂度:O(N), N 给定的所有集合的总的元素个数.
  • 返回值:并集的元素个数。
示例:
127.0.0.1:6379> sadd myset1 a b c d e f
(integer) 6
127.0.0.1:6379> sadd myset2 a c f h i
(integer) 5
127.0.0.1:6379> sunion myset1 myset2
1) "d"
2) "c"
3) "a"
4) "i"
5) "h"
6) "b"
7) "f"
8) "e"
127.0.0.1:6379> sunionstore myret myset1 myset2
(integer) 8
127.0.0.1:6379> smembers myret
1) "d"
2) "c"
3) "a"
4) "i"
5) "h"
6) "b"
7) "f"
8) "e"

2.5 SDIFF

获取给定set的差集中的元素

SDIFF key [key ...]
  • 时间复杂度:O(N), N 给定的所有集合的总的元素个数.
  • 返回值:差集的元素。
示例:
127.0.0.1:6379> sadd myset1 a b c d e f
(integer) 6
127.0.0.1:6379> sadd myset2 a c f h i
(integer) 5
127.0.0.1:6379> sdiff myset1 myset2
1) "b"
2) "d"
3) "e"

2.6 SDIFFSTORE

获取给定set的差集中的元素并存储到指定的set中

SDIFFSTORE destination key [key ...]
  • 时间复杂度:O(N), N 给定的所有集合的总的元素个数.
  • 返回值:差集的元素个数。
示例:
127.0.0.1:6379> sadd myset1 a b c d e f
(integer) 6
127.0.0.1:6379> sadd myset2 a c f h i
(integer) 5
127.0.0.1:6379> sdiffstore myret myset1 myset2
(integer) 3
127.0.0.1:6379> smembers myret
1) "b"
2) "d"
3) "e"

3. 内部编码

集合类型的内部编码有两种:

  • intset(整数集合):当集合中的元素都是整数并且元素的个数⼩于 set-max-intset-entries 配置(默认 512 个)时,Redis 会选⽤ intset 来作为集合的内部实现,从⽽减少内存的使⽤。
  • hashtable(哈希):当集合类型⽆法满⾜ intset 的条件时,Redis 会使⽤ hashtable 作为集合
    的内部实现。

当元素个数较少且都为整数时,内部编码为intset:

127.0.0.1:6379> sadd setkey 1 2 3
(integer) 3
127.0.0.1:6379> object encoding setkey
"intset"

当元素个数多于512个时,内部编码为hashtable:

127.0.0.1:6379> sadd setkey 1 2 3 4
(integer) 513
127.0.0.1:6379> object encoding setkey
"hashtable

当元素中有非整数类型时,内部编码为hashtable:

127.0.0.1:6379> sadd setkey 1 2 3
(integer) 3
127.0.0.1:6379> object encoding setkey
"intset"
127.0.0.1:6379> sadd setkey hello
(integer) 1
127.0.0.1:6379> object encoding setkey
"hashtable"

四、Zset(有序集合)

有序集合和集合一样,都不能有重复元素,它于集合最大的区别就是它是有序,它是每个元素关联一个分数(score)的方式来确保有序

有序集合提供了获取指定分数和元素范围查找、计算成员排名等功能

1. 普通命令

1.1 ZADD

添加或更新指定的元素及分数到zset中,分数应该符合double类型,+inf/-inf作为正负极限也是合法的

ZADD相关选项:

  • XX:仅仅⽤于更新已经存在的元素,不会添加新元素。
  • NX:仅⽤于添加新元素,不会更新已经存在的元素。
  • CH:默认情况下,ZADD 返回的是本次添加的元素个数,但指定这个选项之后,就会还包含本次更新的元素的个数。
  • INCR:此时命令类似 ZINCRBY 的效果,将元素的分数加上指定的分数。此时只能指定⼀个元素和分数。
ZADD key [NX | XX] [GT | LT] [CH] [INCR] score member [score member...]
  • 时间复杂度:O(log(N))
  • 返回值:本次添加成功的元素个数。
示例:
127.0.0.1:6379> zadd myzset 1 one 2 two 3 three
(integer) 3
127.0.0.1:6379> zrange myzset 0 -1 withscores
1) "one"
2) "1"
3) "two"
4) "2"
5) "three"
6) "3"
127.0.0.1:6379> zadd myzset 10 one
(integer) 0
127.0.0.1:6379> zrange myzset 0 -1 withscores
1) "two"
2) "2"
3) "three"
4) "3"
5) "one"
6) "10"
127.0.0.1:6379> zadd myzset ch 20 two 30 three
(integer) 2
127.0.0.1:6379> zrange myzset 0 -1 withscores
1) "one"
2) "10"
3) "two"
4) "20"
5) "three"
6) "30"

1.2 ZCARD

获取一个zset的基数,即zset中的元素个数

ZCARD key
  • 时间复杂度:O(1)
  • 返回值:zset 内的元素个数。
示例:
127.0.0.1:6379> zrange myzset 0 -1
1) "one"
2) "two"
3) "three"
127.0.0.1:6379> zcard myzset
(integer) 3

1.3 ZCOUNT

返回分数在min和max之间的元素的个数,默认情况下min和max都是包含的,可以通过( 排除

ZCOUNT key min max
  • 时间复杂度:O(log(N))
  • 返回值:满⾜条件的元素列表个数。
示例:
127.0.0.1:6379> zadd myzset 1 one 2 two 3 three 4 four
(integer) 4
127.0.0.1:6379> zcount myzset 1 4
(integer) 4
127.0.0.1:6379> zcount myzset (1 (4
(integer) 2

1.4 ZRANGE

返回指定区间内的元素,元素按升序,带上withscores可以把分数也返回

此处的 [start, stop] 为下标构成的区间. 从 0 开始, ⽀持负数.
ZRANGE key start stop [WITHSCORES]
  • 时间复杂度:O(log(N)+M)
  • 返回值:区间内的元素列表。
示例:
127.0.0.1:6379> zadd myzset 1 one 2 two 3 three 4 four
(integer) 4
127.0.0.1:6379> zrange myzset 1 4
1) "two"
2) "three"
3) "four"

1.5 ZREVRANGE

返回指定区间内的元素,元素按照降序,带上withscores可以把分数也返回

ZREVRANGE key start stop [WITHSCORES]
  • 时间复杂度:O(log(N)+M)
  • 返回值:区间内的元素列表。
示例:
127.0.0.1:6379> zadd myzset 1 one 2 two 3 three 4 four
(integer) 4
127.0.0.1:6379> zrevrange myzset 1 4
1) "three"
2) "two"
3) "one"

1.6 ZRANGEBYSCORE

返回分数在min和max之间的元素,默认情况下min和max都包含,可以通过( 排除

ZRANGEBYSCORE key min max [WITHSCORES]
  • 时间复杂度:O(log(N)+M)
  • 返回值:区间内的元素列表。
示例:
127.0.0.1:6379> zadd myzset 1 one 2 two 3 three 4 four
(integer) 4
127.0.0.1:6379> zrangebyscore myzset 1 4
1) "one"
2) "two"
3) "three"
4) "four"
127.0.0.1:6379> zrangebyscore myzset (1 (4
1) "two"
2) "three"

1.7 ZPOPMAX

删除并返回分数最高的count个元素

ZPOPMAX key [count]
  • 时间复杂度:O(log(N) * M)
  • 返回值:分数和元素列表。
示例:
127.0.0.1:6379> zpopmax myzset 
1) "four"
2) "4"
127.0.0.1:6379> zpopmax myzset 3
1) "three"
2) "3"
3) "two"
4) "2"
5) "one"
6) "1"

1.8 ZPOPMIN

删除并返回分数最低的count个元素

ZPOPMIN key [count]
  • 时间复杂度:O(log(N) * M)
  • 返回值:分数和元素列表。
示例:
127.0.0.1:6379> zadd myzset 1 one 2 two 3 three 4 four
(integer) 4
127.0.0.1:6379> zpopmin myzset 
1) "one"
2) "1"
127.0.0.1:6379> zpopmin myzset 3
1) "two"
2) "2"
3) "three"
4) "3"
5) "four"
6) "4"

1.9 BZPOPMIN

zpopmin的阻塞版本

BZPOPMIN key [key ...] timeout
  • 时间复杂度:O(log(N))
  • 返回值:元素列表。

1.10 ZRANK

按照升序返回指定元素的排名

ZRANK key member
  • 时间复杂度:O(log(N))
  • 返回值:排名。
示例:
127.0.0.1:6379> zadd myzset 1 one 2 two 3 three 4 four
(integer) 4
127.0.0.1:6379> zrank myzset two
(integer) 1
127.0.0.1:6379> zrank myzset one
(integer) 0
127.0.0.1:6379> zrange myzset 0 -1
1) "one"
2) "two"
3) "three"
4) "four"

1.11 ZREVRANK

按降序返回指定元素的排名

ZREVRANK key member
时间复杂度:O(log(N))
返回值:排名。
示例:
127.0.0.1:6379> zadd myzset 1 one 2 two 3 three 4 four
(integer) 4
127.0.0.1:6379> zrange myzset 0 -1
1) "one"
2) "two"
3) "three"
4) "four"
127.0.0.1:6379> zrevrank myzset one
(integer) 3
127.0.0.1:6379> zrevrank myzset four
(integer) 0

1.11 ZSCORE

返回指定元素的分数

ZSCORE key member
  • 时间复杂度:O(1)
  • 返回值:分数。
示例:
127.0.0.1:6379> zadd myzset 1 one 2 two 3 three 4 four
(integer) 4
127.0.0.1:6379> zscore myzset one
"1"

1.12 ZREM

删除指定的元素

ZREM key member [member ...]
  • 时间复杂度:O(M*log(N))
  • 返回值:本次操作删除的元素个数。
示例:
127.0.0.1:6379> zrange myzset 0 -1
1) "one"
2) "two"
3) "three"
4) "four"
127.0.0.1:6379> zrem myzset one two
(integer) 2
127.0.0.1:6379> zrange myzset 0 -1
1) "three"
2) "four"

1.13 ZREMRANGEBYRANK

按照排序,升序删除指定范围内的元素,左闭右闭

ZREMRANGEBYRANK key start stop
  • 时间复杂度:O(log(N)+M)
  • 返回值:本次操作删除的元素个数。
示例:
127.0.0.1:6379> zrange myzset 0 -1 withscores
1) "one"
2) "1"
3) "two"
4) "2"
5) "three"
6) "3"
7) "four"
8) "4"
127.0.0.1:6379> zremrangebyrank myzset 1 2
(integer) 2
127.0.0.1:6379> zrange myzset 0 -1
1) "one"
2) "four"

1.14 ZREMRANGEBYSCORE

按照分数删除指定区间内的元素,左闭右闭

ZREMRANGEBYSCORE key min max
  • 时间复杂度:O(log(N)+M)
  • 返回值:本次操作删除的元素个数。
示例:
127.0.0.1:6379> zrange myzset 0 -1 withscores
1) "one"
2) "1"
3) "two"
4) "2"
5) "three"
6) "3"
7) "four"
8) "4"
127.0.0.1:6379> zremrangebyscore myzset 1 2
(integer) 2
127.0.0.1:6379> zrange myzset 0 -1 withscores
1) "three"
2) "3"
3) "four"
4) "4"

1.15 ZINCRBY

为指定元素的关联分数添加指定的分数值

ZINCRBY key increment member
  • 时间复杂度:O(log(N))
  • 返回值:增加后元素的分数。
示例:
127.0.0.1:6379> zscore myzset four
"4"
127.0.0.1:6379> zincrby myzset 10 four
"14"
127.0.0.1:6379> zscore myzset four
"14"
127.0.0.1:6379> zincrby myzset -10 four
"4"
127.0.0.1:6379> zscore myzset four
"4"

2. 集合间操作

2.1 ZINTERSTORE

求出给定有序集合的交集并保存到目标集合中,在合并中元素按照约定好的权重计算后相加写入目标有序集合中

ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight[weight ...]] [AGGREGATE <SUM | MIN | MAX>]
  • 时间复杂度:O(N*K)+O(M*log(M)) N 是输⼊的有序集合中, 最⼩的有序集合的元素个数; K 是输⼊了⼏个有序集合; M 是最终结果的有序集合的元素个数.
  • 返回值:⽬标集合中的元素个数
示例:
127.0.0.1:6379> zadd zset1 1 one 2 two
(integer) 2
127.0.0.1:6379> zadd zset2 1 one 2 two
(integer) 2
127.0.0.1:6379> zinterstore myzset 2 zset1 zset2 weights 2 3
(integer) 2
127.0.0.1:6379> zrange myzset 0 -1 withscores
1) "one"
2) "5"
3) "two"
4) "10"

2.2 ZUNIONSTORE

求出给定有序集合中元素的并集并保存进⽬标有序集合中,在合并过程中以元素为单位进⾏合并,元素对应的分数按照不同的聚合⽅式和权重得到新的分数。
ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight[weight ...]] [AGGREGATE <SUM | MIN | MAX>]
  • 时间复杂度:O(N)+O(M*log(M)) N 是输⼊的有序集合总的元素个数; M 是最终结果的有序集合的元素个数.
  • 返回值:⽬标集合中的元素个数
示例:
redis> ZADD zset1 1 "one"
(integer) 1
redis> ZADD zset1 2 "two"
(integer) 1
redis> ZADD zset2 1 "one"
(integer) 1
redis> ZADD zset2 2 "two"
(integer) 1
redis> ZADD zset2 3 "three"
(integer) 1
redis> ZUNIONSTORE out 2 zset1 zset2 WEIGHTS 2 3
(integer) 3
redis> ZRANGE out 0 -1 WITHSCORES
1) "one"
2) "5"
3) "three"
4) "9"
5) "two"
6) "10"

3. 内部编码

有序集合类型的内部编码有两种:

  • ziplist(压缩列表):当有序集合的元素个数⼩于 zset-max-ziplist-entries 配置(默认 128 个),同时每个元素的值都⼩于 zset-max-ziplist-value 配置(默认 64 字节)时,Redis 会⽤ ziplist 来作为有序集合的内部实现,ziplist 可以有效减少内存的使⽤。
  • skiplist(跳表):当 ziplist 条件不满⾜时,有序集合会使⽤ skiplist 作为内部实现,因为此时
    ziplist 的操作效率会下降。

当元素个数较少且每个元素大小较小时,内部编码为ziplist:

127.0.0.1:6379> zadd zsetkey 50 e1 60 e2 30 e3
(integer) 3
127.0.0.1:6379> object encoding zsetkey
"ziplist"

当元素个数超过128个时,内部编码为skiplist:

127.0.0.1:6379> zadd zsetkey 50 e1 60 e2 30 e3 ... 省略 ... 82 e129
(integer) 129
127.0.0.1:6379> object encoding zsetkey
"skiplist"

当某个元素大于64字节时,内部编码为skiplist:

127.0.0.1:6379> zadd zsetkey 50 "one string bigger than 64 bytes ... 省略 ..."
(integer) 1
127.0.0.1:6379> object encoding zsetkey
"skiplist"

五、总结

以上四个加上String类型就是Redis中最常用的五种数据类型,这五种数据类型已经能囊括大部分的使用场景,在有些特殊场景我们或许还是需要借助另外五个数据类型,那五种数据类型也不是很难,用到的时候再自己查文档学习即可


感谢各位大佬观看,创作不易,还望各位大佬点赞支持!!!

http://www.dtcms.com/a/453533.html

相关文章:

  • 探讨生成式AI在代码评审与重构中的决策权重分配
  • 【LeetCode380题】和【LeetCode238题】题解
  • The “Launch”_2 - 价值交付与灰度发布的系统实现方案
  • 做的网站怎么打开是白板静态网站 价格
  • JavaScript Boolean(布尔)
  • CentOS 7.6 系统源码部署 HivisionIDPhotos
  • 电子电气架构 --- 汽车座舱行业发展现状分析
  • 李建忠 电子商务网站建设与管理 pptwordpress百度不收录文章
  • 算法入门:专题攻克一---双指针(3)有效三角形的个数
  • 怎么做才能提高网站权重360建筑网证书估价
  • IPTV Pro 9.1.9| 空壳直播软件,可导入直播源
  • 【高级】系统架构师 | 2025年上半年案例分析真题DAY1
  • 图片上传网站变形的处理新浪微博登录网页版
  • OpenCV(二):加载图片
  • 免费的网站推广怎么做效果好服务营销策划方案
  • 【征文计划】Rokid 语音唤醒技术深度解析:从声学模型到低功耗优化实践
  • Linux---进程信号
  • 从汽车传动到航空航天:滚珠花键的跨领域精密革命
  • 电子电气架构 --- 汽车座舱市场发展核心方向
  • leetcode 69.x的平方根
  • 网站建设策划方案书论文免费seo诊断
  • 【密码学实战】openHiTLS keymgmt命令行:密钥管理工具
  • 网站上线倒计时html5模板企业培训机构有哪些
  • 中型规模生产架构部署详细步骤
  • 如何加强英文网站建设重庆网站建设的公司哪家好
  • 逆向分析文档:基于 app.endata.com.cn 票房数据接口的加密与解密流程
  • 为什么做腾讯网站如何压缩网站
  • 吴恩达机器学习课程(PyTorch适配)学习笔记:1.1 基础模型与数学原理
  • 【全志V821_FoxPi】6-1 MIPI协议与MIPI摄像头
  • 【防火墙源码】WordPress防火墙插件1.0测试版