前言

上篇文章介绍了Redis 数据库的部分命令,本篇文章介绍剩余相关命令。

EXISTS

可用版本:>= 1.0.0

时间复杂度:O(N),N为数据库key的数量

命令格式

1
EXISTS key [key ...]

命令描述

  • 判断给定的key是否存在

返回值

返回数据库中,key存在的数量。

如果给定了相同的key,同样会计数。比如somekey存在,返回1;给定somekey somekey,返回2。

示例

1
2
3
4
5
6
127.0.0.1:6379> set user:1:name jack
OK
127.0.0.1:6379> exists user:1:name
(integer) 1
127.0.0.1:6379> exists user:1:age
(integer) 0

TYPE

可用版本:>= 1.0.0

时间复杂度:O(1)

命令格式

1
TYPE key

命令描述

  • 返回 key 所储存的值的类型

返回值

  • string
  • list
  • set
  • zset
  • hash
  • Stream

示例

1
2
3
4
127.0.0.1:6379> set user:1:name jack
OK
127.0.0.1:6379> type user:1:name
string

RENAME

可用版本:>= 1.0.0

时间复杂度:O(1)

命令格式

1
RENAME key newkey

命令描述

  • key重命名为newkey

  • 如果key不存在,返回error

  • 如果newkey已经存在,newkey对应的数据会被覆盖,也就是会先执行删除newkey操作,然后重命名。如果newkey存储的数据量较大,那么删除操作会导致较多耗时。

  • 3.2.0及之前版本,如果keynewkey一样,会返回error

返回值

字符串:OK 或者 error

示例

1
2
3
4
5
6
127.0.0.1:6379> set user:1:name jack
OK
127.0.0.1:6379> rename user:1:name user:2:name
OK
127.0.0.1:6379> get user:2:name
"jack"

RENAMENX

可用版本:>= 1.0.0

时间复杂度:O(1)

命令格式

1
RENAMENX key newkey

命令描述

  • newkey不存在时,将key重命名为newkey

  • 如果key不存在,返回error

  • 3.2.0及之前版本,如果keynewkey一样,会返回error

返回值

整数值:

1:重命名成功

0:newkey已存在,重命名失败

示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
127.0.0.1:6379> set user:1:name jack
OK
127.0.0.1:6379> set user:2:name peter
OK
# user:2:name 已经存在,重命名失败
127.0.0.1:6379> renamenx user:1:name user:2:name
(integer) 0
# 重命名成功
127.0.0.1:6379> renamenx user:1:name user:3:name
(integer) 1
127.0.0.1:6379> get user:3:name
"jack"

MOVE

可用版本:>= 1.0.0

时间复杂度:O(1)

命令格式

1
MOVE key db

命令描述

  • 将当前数据库的 key 移动到给定的数据库 db

  • 如果key已经存在于目标db,或者key在当前数据库不存在,不会执行任何操作。因此,可以利用该特性,将 MOVE 当作锁(locking)原语(primitive)。

返回值

整数值:

1:移动成功

0:移动失败

示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
127.0.0.1:6379> select 0
OK
127.0.0.1:6379> set user:1:name jack
OK
127.0.0.1:6379> move user:1:name 1  # 移动到数据库1
(integer) 1
127.0.0.1:6379> exists user:1:name  # 数据库0不存在该key了
(integer) 0
127.0.0.1:6379> select 1  #选择数据库1
OK
127.0.0.1:6379[1]> exists user:1:name  # key存在
(integer) 1

DEL

可用版本:>= 1.0.0

时间复杂度:O(N),N为要移除的key的数量。当key对应的结构是String时,单个key对应的复杂度是O(M),key对应的结构是是list、set、sorted set、hash时,单个key对应的复杂度为O(M)。

命令格式

1
DEL key [key ...]

命令描述

  • 将key对应的数据从数据库中移除

  • 如果key不存在,不会执行操作

返回值

整数值:被移除的key数量

示例

1
2
3
4
5
6
7
8
127.0.0.1:6379> set user:1:name jack
OK
127.0.0.1:6379> exists user:1:name
(integer) 1
127.0.0.1:6379> del user:1:name
(integer) 1
127.0.0.1:6379> exists user:1:name
(integer) 0

RANDOMKEY

可用版本:>= 1.0.0

时间复杂度:O(1)

命令格式

1
RANDOMKEY

命令描述

  • 从当前数据库中随机返回一个key

返回值

字符串:key 或者 nil(数据库为空)

示例

1
2
3
4
5
6
7
8
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> mset name jack age 10 gender male
OK
127.0.0.1:6379> randomkey
"age"
127.0.0.1:6379> randomkey
"name"

SORT

可用版本:>= 1.0.0

时间复杂度:O(N+M*log(M)),其中N为集合中的元素数量,M为返回的元素数量。如果不排序返回,时间复杂度为O(N)

命令格式

1
2
SORT key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern ...]] 
[ASC|DESC] [ALPHA] [STORE destination]

命令描述

返回或者保存给定集合中排序好的元素;

自Redis 7.0,SORT_RO命令是只读版本的SORT;

默认情况下,值被解释为双精度浮点数进行排序,最简单的形式为:

1
SORT mylist

假设mylist中存储的是数值类型的值,该命令会按照从小到大的顺序,返回mylist中所有的值。如果想要返回从大到小的顺序,使用DESC参数:

1
SORT mylist DESC

如果mylist中存储的是字符串,并且想按照字典序排序,可以使用ALPHA参数:

1
SORT mylist ALPHA

LIMIT参数

可以使用LIMIT参数,来限制返回的元素范围,接受 offsetcount 两个参数:

  • offset 指定要跳过的元素数量;
  • count 指定跳过 offset 个指定的元素之后,要返回多少个对象;

下例会返回前十个元素

1
SORT mylist LIMIT 0 10

可以通过多个参数组合,来实现想要的需求。比如下例:使用字典序,倒序排序,返回前五个元素

1
SORT mylist LIMIT 0 5 ALPHA DESC

使用外部key排序

有时候我们想要使用外部的key作为权重来进行排序,例如:一个list中存储的是用户的id:1,2,3,同时还有user_1,user_2,user_3这三个key保存中用户的年龄,我们想根据用户的年龄对id进行排序,就可以使用外部key排序这个功能。

sort mylist by user_* 的意思就是,使用 mylist 中的数据,拼成的user_* 这个格式的 key 对应的数据来排序。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
127.0.0.1:6379> lpush mylist 1 2 3
(integer) 3
127.0.0.1:6379> set user_1 10
OK
127.0.0.1:6379> set user_2 15
OK
127.0.0.1:6379> set user_3 8
OK
127.0.0.1:6379> sort mylist by user_*
1) "3"
2) "1"
3) "2"

GET选项

使用 GET 选项,可以根据排序的结果来取出相应的键值。

比如说,以下代码先排序 uid , 再取出键 user_name_{uid} 的值:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
127.0.0.1:6379> lpush id_list 1 2 3
(integer) 3
127.0.0.1:6379> set user_name_1 jack
OK
127.0.0.1:6379> set user_name_2 peter
OK
127.0.0.1:6379> set user_name_3 rose
OK
127.0.0.1:6379> sort id_list GET user_name_*1
) "jack"  # id = 12
) "peter" # id = 23
) "rose"  # id = 3

同时,我们可以组合使用 BY 和 GET选项,完成更复杂的排序查询:下例中,查询id_list中的所有id,然后使用 user_age_{id} 作为key 对id 进行排序,然后取出user_name_{id} 作为key对应的值。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
127.0.0.1:6379> lpush id_list 1 2 3
(integer) 3
127.0.0.1:6379> set user_name_1 jack
OK
127.0.0.1:6379> set user_name_2 peter
OK
127.0.0.1:6379> set user_name_3 rose
OK
127.0.0.1:6379> set user_age_1 10
OK
127.0.0.1:6379> set user_age_2 15
OK
127.0.0.1:6379> set user_age_3 8
OK
127.0.0.1:6379> sort id_list BY user_age_* GET user_name_*1
) "rose"  # age=8 name=rose id=32
) "jack"	 # age=10 name=jack id=1 3
) "peter" # age=15 name=peter id=2 

同时,我们也可以使用多个GET选项,获取多个key对应的值:我们又增加使用了 GET user_age_{id},获取了对应的值。

1
2
3
4
5
6
7
127.0.0.1:6379> sort id_list BY user_age_* GET user_name_* GET user_age_*1
) "rose"
2) "8"
3) "jack"
4) "10"
5) "peter"
6) "15"

使用GET #,可以返回本身的值:比如我们使用使用GET #,返回了id_list 中的id值。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
127.0.0.1:6379> sort id_list BY user_age_* GET user_name_* GET user_age_* GET #
1) "rose"
2) "8"
3) "3"
4) "jack"
5) "10"
6) "1"
7) "peter"
8) "15"
9) "2"

如果有些情况下,我们不想排序,而是想获取id关联的相关数据,比如通过id查询出用户的姓名、年龄等,类似于SQL中的join查询,可以通过BY指定一个不存在的key来实现。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
127.0.0.1:6379> sort id_list BY not_exist_key GET # GET user_name_* GET user_age_*
1) "3"
2) "rose"
3) "8"
4) "2"
5) "peter"
6) "15"
7) "1"
8) "jack"
9) "10"

对于Hash结构,我们可以使用如下方式获取数据:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> lpush id_list 1 2 3
(integer) 3
127.0.0.1:6379> hset id_info_1 name jack age 10
(integer) 2
127.0.0.1:6379> hset id_info_2 name peter age 15
(integer) 2
127.0.0.1:6379> hset id_info_3 name rose age 8
(integer) 2
127.0.0.1:6379> sort id_list by id_info_*->age get id_info_*->age get id_info_*->name
1) "8"
2) "rose"
3) "10"
4) "jack"
5) "15"
6) "peter"

STORE选项用于保存结果

默认情况下,查询结果只是返回给客户端,使用STORE参数,我们可以将结果保存到一个key中。

保存的数据默认不会过期,可以通过expire命令对key设置过期时间,这就相当于构建了一个缓存数据,让其他客户端也可以使用。但是为了保证其他客户端不会重建缓存,需要加锁,比如使用SETNX命令实现。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> lpush id_list 1 2 3
(integer) 3
127.0.0.1:6379> set user_name_1 jack
OK
127.0.0.1:6379> set user_name_2 peter
OK
127.0.0.1:6379> set user_name_3 rose
OK
#将查询结果保存至result中
127.0.0.1:6379> sort id_list get user_name_* store result
(integer) 3
127.0.0.1:6379> lrange result 0 -1
1) "jack"
2) "peter"
3) "rose"

返回值

数组:没有指定STORE参数时,返回结果列表

整数:指定STORE参数时,返回保存的元素个数

更多

微信公众号:CodePlayer