速度快
正常情况下,Redis 读写性能可以达到 10 万/秒 ;Redis 所有数据是存放在内存中的、Redis 是用 C 语言实现的、Redis 使用了单线程架构。
基于键值对的数据结构
Redis 的全称是 REmote Dictionary Server,主要提供了 5
种数据结构:字符串(String)
、哈希(Hash)
、列表(List)
、集合(Set)
、有序集合(ZSet)
。
在字符串的基础上演变出了位图(Bitmaps)
、HyperLogLog
两种数据机构,在 Redis3.2 版本中加入有关GEO(地理信息定位)
的功能。
丰富的功能
简单稳定
客户端语言多
持久化
将数据放在内存中是不安全的,一旦发生断电或者机器故障,重要的数据可能就会丢失,因此,Redis 提供了两种持久化方式:RDB
和AOF
,即可以用两种策略将内存的数据保存到硬盘中。
主从复制
Redis 提供了复制功能,实现了多个相同数据的 Redis 副本。
高可用和分布式
Redis 从2.8版本正式提供了高可用实现 Redis Sentinel,它能够保证 Redis 节点的故障发现和故障自动转移。Redis 从3.0版本正式提供了分布式实现 Redis Cluster,它是 Redis 真正的分布式实现,提供了高可用、读写和容量的扩展性。
查看所有键
keys *
会将所有的键输出
键总数
dbsize
返回当前数据库中键的总数。 dbsize 命令在计算键总数时不会遍历所有键,而是直接获取Redis 内置的键总数变量,所以dbsize命令的时间复杂度是o(1)。而keys命令会遍历所有键,所以它的时间复杂度是o(n),当Redis中保存了大量键时,线上环境禁止使用。
检查键是否存在
exists key
如果存在则返回1,不存在则返回0。
删除键
del key [key ...]
返回结果为成功删除键的个数,假设删除一个不存在的键,就会返回0
键过期
expire key seconds
Redis 支持对键添加过期时间,当超过期时间后,会自动删除键。
ttl key
返回键的剩余过期时间,有3中返回值
键的数据结构类型
type key
例如键是字符串类型,返回结果为string,键是列表类型,返回结果为list,如果键不存在,返回 none
type
命令实际返回的是当前键的数据结构类型(5种数据类型),但这些只是Redis对外的数据结构。
实际上每种数据结构都有自己底层的内部编码实现,而且是多种实现,这样Redis会在合适的场景选择合适的内部编码
我们可以通过object encoding key
查询内部编码。
Redis 这样设计有2个好处:
字符串类型是Redis最基础的数据结构。字符串的值最大不能超过512MB
命令
设置值
set key value [ex seconds] [px milliseconds] [nx|xx]
除了 set 选项,Redis 还提供了 setex
和 setnx
两个命令,它们的作用和 ex 和 nx 选项是一样的:
setex key seconds value
setnx key value
获取值
get key
如果获取的键不存在,则返回nil(空)
批量设置值
mset key value [key value ...]
批量获取值
mget key [key ...]
如果有些键不存在,那么它的值为nil(空),结果是按照传入键的顺序返回
计数
incr key
incr命令用于对值做自增的操作,返回结果分为3
种情况:
除了incr
命令,Redis提供了decr(自减)
、incrby(自增指定数字)
、decrby(自减指定数字)
、incrbyfloat(自增浮点数)
decr key
incrby key increment
decrby key decrement
incrbyfloat key increment
追加值
append key value
append可以向字符串尾部追加值
字符串长度
strlen key
eg:当前值为redisworld,所以返回值为10,当前值为世界,返回值为6(每个中文占用3个字节)
设置并返回原值
getset key value
getset和set一样会设置值,但是不同的是,它同时会返回键原来的值
设置指定位置的字符
setrange key offset value
下面操作将值由pest变为了best
127.0.0.1:6379> set redis pest
OK
127.0.0.1:6379> setrange redis 0 b
(integer) 4
127.0.0.1:6379> get redis
"best"
127.0.0.1:6379> setrange redis 2 a
(integer) 4
127.0.0.1:6379> get redis
"beat"
127.0.0.1:6379> setrange redis 6 c
(integer) 7
127.0.0.1:6379> get redis
"beat\x00\x00c"
127.0.0.1:6379>
获取部分字符串
getrange key start end
start 和 end 分别是开始和结束的偏移量,偏移量从0开始计算
127.0.0.1:6379> getrange redis 0 1
"be"
127.0.0.1:6379> getrange redis 9 10
""
127.0.0.1:6379> getrange redis 4 10
"\x00\x00c"
127.0.0.1:6379> getrange redis 3 10
"t\x00\x00c"
127.0.0.1:6379>
命令 | 时间复杂度 |
---|---|
set key value | o(1) |
get key | o(1) |
del key [key …] | o(k),k是键的个数 |
mset key value [key value …] | o(k),k是键的个数 |
mget key [key …] | o(k),k是键的个数 |
incr key | o(1) |
decr key | o(1) |
incrby key increment | o(1) |
decrby key increment | o(1) |
incrbyfloat key increment | o(1) |
append key value | o(1) |
strlen key | o(1) |
setrange key offset value | o(1) |
getrange key start end | o(n),n是字符串长度,由于获取字符串非常快,所以如果字符串不是很长,可以视同为o(1) |
在 Redis 中,哈希类型是指键值本身又是一个键值对结构。
命令
设置值
hset key field value
下面为user:1 添加一对 field-value
127.0.0.1:6379> hset user:1 name tom
(integer) 1
如果field已经存在,执行上述命令返回 0,但实际的值发生改变
127.0.0.1:6379> hset user:1 name ddddd
(integer) 0
此外,Redis 提供了hsetnx
命令,它们的关系就像set和setnx命令一样,只不过作用域由键变为field
获取值
hget key field
下面的操作获取user:1的name域(属性)对应的值,如果键或field不存在,会返回nil
127.0.0.1:6379> hget user:1 name
"tom"
127.0.0.1:6379> hget user:1 namea
(nil)
删除field
hdel key field [field ...]
hedl 会删除一个或多个field,返回结果为成功删除field的个数
计算field个数
hlen key
例如:user:1 有3个field
127.0.0.1:6379> hset user:1 name gy
(integer) 1
127.0.0.1:6379> hset user:1 age 26
(integer) 1
127.0.0.1:6379> hset user:1 city hz
(integer) 1
127.0.0.1:6379> hlen user1:1
(integer) 0 #key不存在返回值
127.0.0.1:6379> hlen user:1
(integer) 3
批量设置或获取field-value
hmset key field value [field value ...]
hmget key field [field...]
hmset和hmget分别是设置和获取field-value,hmset需要的参数是key和多对field-value,hmget需要的参数是key和多个field。
127.0.0.1:6379> HMSET user:1 name huang age 12 city xian
OK
127.0.0.1:6379> hmget user:1 name age citu city aa
1) "huang"
2) "12"
3) (nil) #field不存在
4) "xian"
5) (nil) #field不存在
判断field是否存在
hexists key field
例如,user:1包含name域,所以返回结果为1,不包含时返回0
127.0.0.1:6379> HEXISTS user:1 name
(integer) 1
127.0.0.1:6379> HEXISTS user:1 name22
(integer) 0
127.0.0.1:6379>
获取所有field
hkeys key
hkeys命令应该叫hfields更为恰当,他返回指定哈希键所有的field,例如
127.0.0.1:6379> hkeys user:1
1) "name"
2) "age"
3) "city"
127.0.0.1:6379> hkeys user:11 #键不存在
(empty list or set)
127.0.0.1:6379>
获取所有value
hvals key
获取 user:1全部value
127.0.0.1:6379> hvals user:1
1) "huang"
2) "12"
3) "xian"
127.0.0.1:6379> hvals user:12
(empty list or set)
获取所有的field-value
hgetall key
获取user:1所有的field-value
127.0.0.1:6379> hgetall uset:1 #key不存在的情况
(empty list or set)
127.0.0.1:6379> hgetall user:1
1) "name"
2) "huang"
3) "age"
4) "12"
5) "city"
6) "xian"
127.0.0.1:6379>
在使用 hgetall时,如果哈希元素个数比较多,会存在阻塞 Redis 的可能。如果开发人员只需要获取部分field,可以使用hmget,如果一定要获取全部field-value,可以使用hscan命令,该命令会渐进式遍历哈希类型
hincrby hincrbyfloat
hincrby key field
hincrbyfloat key field
就像incrby、incrbyfloat命令一样,但是它们的作用域是field
计算value的字符串长度(需要Redis 3.2以上)
hstrlen key field
例如:hget user:1 name 的 value 是 tom,那么hstrlen 的返回结果就是3
命令 | 时间复杂度 |
---|---|
hset key field value | o(1) |
hget key field | o(1) |
hdel key field [field …] | o(k),k是field个数 |
hlen key | o(1) |
hgetall key | o(n),n是field总数 |
hmget field [field …] | o(k),k是field的个数 |
hmset field value [field value] | o(k),k是field的个数 |
hexists key field | o(1) |
hkeys key | o(n),n是field总数 |
hvals key | o(n),n是field总数 |
hsetnx key field value | o(1) |
hincrby key field increment | o(1) |
hincrbyfloat key field increment | o(1) |
hstrlen key field | o(1) |
列表(list)类型是用来存储多个有序的字符串。列表的每个字符串称为元素(element),一个列表最多可以存储2^32-1个元素。
在 Redis 中,可以对列表两端插入(push)和弹出(pop),还可以获取指定范围的元素列表、获取指定索引下标的元素等。
列表的四种操作类型
操作类型 | 操作 |
---|---|
添加 | rpush lpush linsert |
查询 | lrange lindex llen |
删除 | lpop rpop lrem ltrim |
修改 | lset |
阻塞操作 | bloop brpop |
添加操作
从右边插入元素
rpush key value [value ...]
下面代码从右向左插入元素c、b、a:
127.0.0.1:6379> rpush listkey c b a
(integer) 3
lrange 0 -1
命令可以从左到右获取列表所有元素
127.0.0.1:6379> rpush listkey c b a
(integer) 3
127.0.0.1:6379> lpush listkey e f g #左边插入
(integer) 6
127.0.0.1:6379> lrange listkey 0 -1
1) "g"
2) "f"
3) "e"
4) "c"
5) "b"
6) "a"
127.0.0.1:6379> rrange listkey 0 -1
(error) ERR unknown command `rrange`, with args beginning with: `listkey`, `0`, `-1`,
从左边插入元素
lpush key value [value ...]
使用方法和 rpush 相同,只不过从左侧插入
向某个元素前或者后插入元素
linsert key before|after pivot value
linsert 命令会从列表中找到等于 pivot(中枢) 的元素,在其前(before)或者后(after)插入一个 新的元素value。
下面操作将会在列表的元素b前插入java,返回结果为4,代表当前命令的长度
127.0.0.1:6379> rpush mylist c b a
(integer) 3
127.0.0.1:6379> LRANGE mylist 0 -1
1) "c"
2) "b"
3) "a"
127.0.0.1:6379> linser mylist before b java
(error) ERR unknown command `linser`, with args beginning with: `mylist`, `before`, `b`, `java`,
127.0.0.1:6379> linsert mylist before b java
(integer) 4
127.0.0.1:6379> LRANGE mylist 0 -1
1) "c"
2) "java"
3) "b"
4) "a"
查找
获取指定范围内的元素列表
lrange key start end
lrange 操作会获取列表指定索引范围所有的元素。索引下标有两个特点:
索引下标从左到右分别是0到N-1,但是从右到左分别是-1到-N
lrange中的 end 选项包含了自身,这个和很多编程语言不包含 end 不太相同,例如像获取列表的第 2 到 第 4 个元素,可以执行如下操作:
127.0.0.1:6379> lrange mylist 1 3
1) "java"
2) "b"
3) "a"
127.0.0.1:6379>
127.0.0.1:6379> lrange mylist 0 1
1) "c"
2) "java"
127.0.0.1:6379> lrange mylist 0 7
1) "c"
2) "java"
3) "b"
4) "a"
127.0.0.1:6379> lrange mylist -1 -3
(empty list or set)
127.0.0.1:6379> lrange mylist -4 -1
1) "c"
2) "java"
3) "b"
4) "a"
127.0.0.1:6379> lrange mylist -5 -1
1) "c"
2) "java"
3) "b"
4) "a"
获取列表指定索引下标的元素
lindex key index
例如,当前列表最后一个元素为a:
127.0.0.1:6379> lindex mylist -1
"a"
127.0.0.1:6379> lindex mylist 0
"c"
127.0.0.1:6379>
获取列表长度
llen key
例如,下面表示当前列表长度为4
127.0.0.1:6379> llen mylist
(integer) 4
127.0.0.1:6379> llen mylist2
(integer) 0 #key值不存在返回的0
127.0.0.1:6379>
删除
从列表左侧弹出元素
lpop key
如下操作将列表最左侧的元素c会被弹出(弹出后,元素被删除),弹出后列表变为 java、b、a:
127.0.0.1:6379> lrange mylist 0 -1
1) "c"
2) "java"
3) "b"
4) "a"
127.0.0.1:6379> lpop mylist
"c" #弹出的元素
127.0.0.1:6379> lrange mylist 0 -1
1) "java"
2) "b"
3) "a"
从列表右侧弹出
rpop key
它的使用方法和lpop是一样的,只不过从列表右侧弹出。
127.0.0.1:6379> lrange mylist 0 -1
1) "java"
2) "b"
3) "a"
127.0.0.1:6379> RPOP mylist
"a"
删除指定元素
lrem key count value
lrem 命令会从列表中找到等于value的元素进行删除,根据count的不同分为三种情况:
count>0,从左到右,删除最多count个元素
count<0,从右到左,删除最多count绝对值个元素
count=0,删除所有
例如,向列表从左向右插入5个a,下面操作将从列表左边开始删除4个为a的元素
127.0.0.1:6379> lpush mylist a a a a a java a
(integer) 7
127.0.0.1:6379> lrange mylist 0 -1
1) "a"
2) "java"
3) "a"
4) "a"
5) "a"
6) "a"
7) "a"
127.0.0.1:6379> lrem list 4 a
(integer) 0
127.0.0.1:6379> lrem mylist 4 a
(integer) 4
127.0.0.1:6379> lrange mylist 0 -1
1) "java"
2) "a"
3) "a"
按照索引范围修建列表
ltrim key start end
例如,下面操作会只保留列表mylist第2个到第4个元素
127.0.0.1:6379> lpush mylist a a a a a java a
(integer) 7
127.0.0.1:6379> lrange mylist 0 -1
1) "a"
2) "java"
3) "a"
4) "a"
5) "a"
6) "a"
7) "a"
127.0.0.1:6379> ltrim mylist 1 3
OK
127.0.0.1:6379> lrange mylist 0 -1
1) "java"
2) "a"
3) "a"
修改
修改指定索引下标的元素
lset key index newValue
下面操作会将列表listkey中的第3个元素设置为python:
127.0.0.1:6379> lrange mylist 0 -1
1) "java"
2) "a"
3) "a"
127.0.0.1:6379> lset mylist 2 python
OK
127.0.0.1:6379> lrange mylist 0 -1
1) "java"
2) "a"
3) "python"
阻塞操作
阻塞式弹出如下:
blpop key [key ...](多个列表的键) timeout(阻塞时间>=0)
brpop key [key ...] (多个列表的键)timeout(阻塞时间>=0)
blpop和brpop 是 lpop 和 rpop 的阻塞版本
列表为空:如果timeout=3,那么客服端要等到3秒后返回,如果timeout=0,那么客户端一直阻塞等待下去
127.0.0.1:6379> brpop list:test 3
(nil)
(3.05s)
127.0.0.1:6379> brpop list:test 0 #命令执行完成后去客户端新增该键值对数据,客户端立即返回
1) "list:test"
2) "ggggg"
(34.77s)
列表命令时间复杂度
操作类型 | 命令 | 时间复杂度 |
---|---|---|
添加 | rpush key value [value …] | o(k),k是元素的个数 |
lpush key value [value …] | o(k),k是元素的个数 | |
linsert key before|after pivot value | o(n),n是pivot距离列表头或尾的距离 | |
查找 | lrange key start end | o(s+n),s是start偏移量,n是start到end的范围 |
lindex key index | o(n),n是索引的偏移量 | |
llen key | o(1) | |
删除 | lpop key | o(1) |
rpop key | o(1) | |
lrem count value | o(n),n是列表的长度 | |
ltrim key start end | o(n),n是要裁剪的元素总数 | |
修改 | lset key index value | o(n),n是索引的偏移量 |
阻塞操作 | blpop brpop | o(1) |
集合(set)类型也是用来保存多个的字符串元素,但和列表类型不一样的是,集合中不允许有重复元素,并且集合中的元素是无序的,不能通过索引下标获取元素。一个集合最多可以存储2^32-1个元素。
Redis除了支持集合内的增删改查,同时还支持多个集合取交集、并集、差集。
命令
集合内操作
添加元素
sadd key member [member ...]
返回结果为添加成功的元素个数。
127.0.0.1:6379> EXISTS myset
(integer) 0
127.0.0.1:6379> sadd myset a b c
(integer) 3
127.0.0.1:6379> sadd myset a b
(integer) 0
删除元素
srem key member [member ...]
返回结果为成功删除元素的个数
127.0.0.1:6379> srem myset a b c
(integer) 3
127.0.0.1:6379> srem myset hello
(integer) 0
计算元素个数
scard key
scard 的时间复查度为O(1),它不会遍历集合所有元素,而是直接使用 Redis 内部的变量
127.0.0.1:6379> scard myset
(integer) 1
判断元素是否在集合中
sismember key element
如果给定元素element在集合内返回1,反之返回0
127.0.0.1:6379> sismember myset a #不存在
(integer) 0
127.0.0.1:6379> sismember myset c
(integer) 1
127.0.0.1:6379> sismember myset1 c #不存在
(integer) 0
随机从集合返回指定个数元素
srandmember key [count]
[count]是可选参数,如果不写默认为1
127.0.0.1:6379> sadd myset a b c
(integer) 3
127.0.0.1:6379> srandmember myset 2
1) "c"
2) "a"
127.0.0.1:6379> srandmember myset 2
1) "c"
2) "b"
127.0.0.1:6379> srandmember myset 2
1) "a"
2) "b"
从集合随机弹出元素
spop key [count]
spop操作可以从集合中随机弹出一个元素
srandmember 和 spop 都是随机从集合中选出元素,两者不同的是spop命令执行后,元素会从集合中删除,而srandmember不会
获取所有元素
smembers key
127.0.0.1:6379> SMEMBERS myset
1) "c"
2) "b"
smembers、lrange、hgetall都属于比较重的命令,如果元素过多存在阻塞Redis的可能性,这时候可以使用sscan来完成。
集合间操作
求多个集合的交集
sinter key [key ...]
127.0.0.1:6379> sadd user:1:follow it music his sports
(integer) 4
127.0.0.1:6379> sadd user:2:follow it news ent sprots
(integer) 4
127.0.0.1:6379> sinter user:1:follow user:2:follow
1) "it"
求多个集合的并集
sunion key [key ...]
127.0.0.1:6379> SUNION user:1:follow user:2:follow
1) "sports"
2) "it"
3) "his"
4) "news"
5) "ent"
6) "music"
7) "sprots"
求多个集合的差集
sdiff key [key ...]
127.0.0.1:6379> sdiff user:1:follow user:2:follow
1) "music"
2) "his"
3) "sports"
将交集、并集、差集的结果保存
sinterstore destination key [key ...]
sunionstore destination key [key ...]
sdiffstore destination key [key ...]
127.0.0.1:6379> SINTERSTORE user:1_2:inter user:1:follow user:2:follow
(integer) 1
127.0.0.1:6379> type user:1_2:inter
set
127.0.0.1:6379> SMEMBERS user:1_2:inter
1) "it"
集合常用命令时间复杂度
命令 | 时间复杂度 |
---|---|
sadd key member [member …] | O(k),k是元素个数 |
srem key member [member …] | O(k),k是元素个数 |
scard key | O(1) |
sismember key member | O(1) |
srandmember key [count] | O(count) |
spop key | O(1) |
smembers key | O(n),n是元素总数 |
sinter key [key …] || sinterstore | O(m*k),k是多个集合中元素最少的个数,m是键个数 |
sunion key [key …] || sunionstore | O(k),k是多个集合元素个数和 |
sdiff key [key …] || sdiffstore | O(k),k是多个集合元素个数和 |
它保留了集合不能有重复成员的特性,增加了有序集合的元素可以排序。但是它和列表使用索引下标作为排序依据不同的是,它给每个元素设置一个分数(score)作为培训的依据。
列表、集合、有序集合三者的异同点
数据结构 | 是否允许重复元素 | 是否有序 | 有序实现方式 | 应用场景 |
---|---|---|---|---|
列表 | 是 | 是 | 索引下标 | 时间轴、消息队列等 |
集合 | 否 | 否 | 无 | 标签、社交等 |
有序集合 | 否 | 是 | 分值(score) | 排行榜系统、社交等 |
命令
集合内
添加成员
zadd key score member [score member ...]
127.0.0.1:6379> zadd user:ranking 251 tom
(integer) 1
127.0.0.1:6379> zadd user:ranking 251 tom
(integer) 0 #返回结果代表成功添加成员的个数
有关zadd命令有2点需要注意:
Redis 3.2 为 zadd 命令添加了nx、xx、ch、incr四个选项
有序集合相比集合提供了排序字段,但是也产生了代价,zadd的时间复杂度为O(log(n)),sadd的时间复杂度为O(1)。
计算成员个数
zcard key
计算某个成员的分数
zscore key member
127.0.0.1:6379> ZSCORE user:ranking tom
"252"
127.0.0.1:6379> ZSCORE user:ranking tomss
(nil) #如果成员不存在返回nil
计算成员的排名
zrank key member
分数低到高返回排名(排序从0开始计算)
zrevrank key member
分数从高到低返回排名(排序从0开始计算)
删除成员
zrem key member [member...]
127.0.0.1:6379> zrem user:ranking mike
(integer) 1 #返回结果为成功删除的个数
增加成员的分数
zincrby key increment member
127.0.0.1:6379> zscore user:ranking tom
"252" #当前数据库中的分数
127.0.0.1:6379> zincrby user:ranking 8 tom
"260" #增加8分后返回的结果
返回指定排名范围的成员
zrange key start end [withscores]
zrevrange key start end [withscores]
有序集合是按照分值排名的,zrange是从低到高返回,zrevrange反之。
如果加上 withscores选项,同时会返回成员的分数:
127.0.0.1:6379> ZRANGE user:ranking 0 2 #返回排名最低的3个成员
1) "kris"
2) "frank"
3) "tim"
127.0.0.1:6379> ZRANGE user:ranking 0 2 withscores
1) "kris"
2) "1"
3) "frank"
4) "200"
5) "tim"
6) "220"
127.0.0.1:6379> ZREVRANGE user:ranking 0 2 withscores
1) "tom"
2) "260"
3) "tom3"
4) "252"
5) "martin"
6) "250"
返回指定分数范围的成员
zrangebyscore key min max [withscores] [limit offset count]
zrevrangebyscore key max min [withscores] [limit offset count]
zrangebyscore 按照分数从低到高返回,zrevrangebyscore反之。
withscores 会同时返回每个成员的分数
limit offset count 选项可以限制输出的起始位置和个数
min和max 支持开区间(小括号)和闭区间(中括号),-inf 和 +inf 分别代表无限小和无限大
127.0.0.1:6379> ZRANGEBYSCORE user:ranking 200 +inf withscores
1) "frank"
2) "200"
3) "tim"
4) "220"
5) "martin"
6) "250"
7) "tom3"
8) "252"
9) "tom"
10) "260"
127.0.0.1:6379> ZRANGEBYSCORE user:ranking 200 +inf withscores limit 2 4
1) "martin"
2) "250"
3) "tom3"
4) "252"
5) "tom"
6) "260"
返回指定分数范围成员个数
zcount key min max
删除指定排名内的升序元素
zremrangebyrank key start end
127.0.0.1:6379> ZREMRANGEBYRANK user:ranking 0 2
(integer) 3 #删除前3个元素
删除指定分数范围的成员
zremrangebyscore key min max
127.0.0.1:6379> ZREMRANGEBYSCORE user:ranking (250 +inf #将250分以上的成员全部删除,返回结果为成功删除的个数
(integer) 2
集合间的操作
交集
zinterstore destination numkeys key [key ...] [weights weight] [aggregate sum|min|max]
下面将对user:ranking:1和user:ranking:2做交集,weights和aggregate使用了默认值,可以看到目标键user:ranking:1_inter_2对分值做了sum操作
127.0.0.1:6379> zadd user:ranking:1 1 kris 91 mike 200 frank 220 tim 250 martin 251 tom
(integer) 6
127.0.0.1:6379> zadd user:ranking:2 8 james 77 mike 625 martin 888 tom
(integer) 4
127.0.0.1:6379> ZINTERSTORE user:ranking:1_inter_2 2 user:ranking:1 user:ranking:2
(integer) 3
127.0.0.1:6379> zrange user:ranking:1_inter_2 0 -1 withscores
1) "mike"
2) "168"
3) "martin"
4) "875"
5) "tom"
6) "1139"
如果想让user:ranking:2的权重变为0.5,并且聚合效果使用max,可以执行如下操作:
127.0.0.1:6379> ZINTERSTORE user:ranking:1_inter_2 2 user:ranking:1 user:ranking:2 weights 1 0.5 aggregate max
(integer) 3
127.0.0.1:6379> zrange user:ranking:1_inter_2 0 -1 withscores
1) "mike"
2) "91"
3) "martin"
4) "312.5"
5) "tom"
6) "444"
并集
zunionstore destination numkeys key [key ...] [weights weight] [aggregate sum|min|max]
有序集合命令的时间复杂度
命令 | 时间复杂度 |
---|---|
zadd key score member [score member …] | O(kxlog(n)),k是添加成员的个数,n是当前有序集合成员个数 |
zcard key | O(1) |
zscore key member | O(1) |
zrank/zrevrank key member | O(log(n)),n是当前有序集合成员个数 |
zrem key member [member …] | O(k*log(n)),k是删除成员的个数,n是当前有序集合成员个数 |
zincrby key increment member | O(log(n)),n是当前有序集合成员个数 |
zrange/zrevrange key start end [withscores] | O(log(n)+k),k是要获取的成员个数,n是当前有序集合成员个数 |
zrangebyscore/zrevrangebyscore key min/max max/min [withscores] | O(log(n)+k),k是要获取的成员个数,n是当前有序集合成员个数 |
zcount key min max | O(log(n)),n是当前有序集合成员个数 |
zremrangebyrank key start end | O(log(n)+k),k是要删除的成员个数,n是当前有序集合成员个数 |
zremrangebyscore key min max | O(log(n)+k),k是要删除的成员个数,n是当前有序集合成员个数 |
zinterstore destination numkeys key [key …] | O(nxk)+O(mxlog(m)),n是成员数量最小的有序集合成员个数,k是有序集合的个数,m是结果集中成员个数 |
zunionstore destination numkeys key [key …] | O(n)+O(mxlog(m)),n是所有有序集合成员个数和,m是结果集中成员个数 |