过期时间
在实际的开发中经常会遇到一些有时效的数据,比如限时优惠活动、缓存或验证码等,过了一定的时间就需要删除这些数据。在关系数据库中一般需要额外的一个字段记录到期时间,然后定期检测删除过期数据。而在Redis中可以使用 EXPIRE
命令设置一个键的过期时间,到时间后Redis会自动删除它。这在缓存、会话管理和临时数据存储等场景中非常有用。
EXPIRE命令使用示例
redis
EXPIRE key seconds
key
:要设置过期时间的键。seconds
:键的过期时间,单位为秒。
返回值
1
:成功设置过期时间。0
:键不存在或设置失败。
redis
# 设置一个键
redis> SET mykey "Hello, Redis!"
OK
# 为 mykey 设置过期时间为 30 秒
redis> EXPIRE mykey 30
(integer) 1
# 检查 mykey 的剩余过期时间
redis> TTL mykey
(integer) 29 # 实际值可能会有所不同,取决于执行时间
# 等待一段时间后再次检查剩余过期时间
# 版本2.6 之后如果key已经过期,返回-2,如果key存在但是没有设置过期时间,返回-1
redis> TTL mykey
(integer) 15 # 实际值可能会有所不同,取决于等待的时间
# 等待过期时间结束后再次检查 mykey 是否存在
redis> EXISTS mykey
(integer) 0
EXPIRE
命令只能设置精确的秒数,不能设置到毫秒级别,如果需要精确到毫秒级别的控制,可以使用 PEXPIRE
命令。
PERSIST
命令用于移除给定键的过期时间,使得该键不会自动过期。如果键已经没有过期时间,PERSIST
命令不会有任何效果。
redis
PERSIST key
key
:要移除过期时间的键。
返回值
1
:成功移除过期时间。0
:键不存在或键已经没有过期时间。
redis
# 设置一个键
redis> SET mykey "Hello, Redis!"
OK
# 为 mykey 设置过期时间为 30 秒
redis> EXPIRE mykey 30
(integer) 1
# 检查 mykey 的剩余过期时间
redis> TTL mykey
(integer) 29 # 实际值可能会有所不同,取决于执行时间
# 使用 PERSIST 命令移除 mykey 的过期时间
redis> PERSIST mykey
(integer) 1
# 再次检查 mykey 的剩余过期时间
redis> TTL mykey
(integer) -1 # 表示键没有过期时间
- 使用
EXPIRE
命令设置键的过期时间,单位为秒。 - 使用
PEXPIRE
命令设置键的过期时间,单位为毫秒。 - 使用
EXPIREAT
命令,通过指定一个Unix时间戳来设置键的过期时间。 - 使用
PEXPIREAT
命令,通过指定一个Unix时间戳(以毫秒为单位)来设置键的过期时间。 - 使用
SETEX
命令,通过指定键的值和过期时间(以秒为单位)来设置键。
注意 :如果 WATCH
命令监控一个拥有过期时间的键,该键因为时间到期而被删除,WATCH
命令不会认为该键被改变。
排序
因为直接使用有序集合不如集合操作强大,当排序不经常使用的时候,可以使用集合存储数据,然后使用 SORT
命令对集合进行排序。
SORT
是 Redis 中一个强大的命令,用于对列表、集合或有序集合中的元素进行排序。它可以接受多个选项来定制排序行为。以下是 SORT
命令的详细使用示例,包括每个参数的解释。
命令格式
sh
SORT key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern ...]] [ASC | DESC] [ALPHA] [STORE destination]
- key:要排序的键,可以是列表、集合或有序集合。
- BY pattern :根据模式指定的键的值进行排序。模式可以包含通配符
{}
,用于引用当前排序元素的值。 - LIMIT offset count :限制排序结果的数量,从
offset
开始,返回count
个元素。 - GET pattern [GET pattern ...] :获取与排序结果相关的其他键的值。模式可以包含通配符
{}
,用于引用当前排序元素的值。 - ASC | DESC :指定排序方向,
ASC
表示升序,DESC
表示降序。 - ALPHA:按字典顺序排序,而不是按数值顺序排序。
- STORE destination:将排序结果存储到指定的键中,而不是返回结果。
一般使用示例
redis
# 添加元素到集合
redis> SADD myset "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z"
# 对列表进行排序,当列表非数字时,ALPHA可以按照字典顺序排序
# DESC 指定降序排序
redis> SORT myset ALPHA DESC
1) "z"
2) "y"
3) "x"
4) "w"
5) "v"
6) "u"
7) "t"
8) "s"
9) "r"
10) "q"
11) "p"
12) "o"
13) "n"
14) "m"
15) "l"
16) "k"
17) "j"
18) "i"
19) "h"
20) "g"
21) "f"
22) "e"
23) "d"
24) "c"
25) "b"
26) "a"
BY 和 GET 参数
BY pattern
参数允许你在排序时根据其他键的值来进行排序。这在需要根据关联数据进行排序的场景中非常有用。下面是一个完整的示例,展示了如何使用 BY pattern
参数。
uid | user_name_{uid} | user_level_{uid} |
---|---|---|
1 | admin | 9999 |
2 | jack | 10 |
3 | peter | 25 |
4 | mary | 70 |
数据表格初始化
redis
LPUSH uid 1
SET user_name_1 admin
SET user_level_1 9999
LPUSH uid 2
SET user_name_2 jack
SET user_level_2 10
LPUSH uid 3
SET user_name_3 peter
SET user_level_3 25
LPUSH uid 4
SET user_name_4 mary
SET user_level_4 70
BY 选项
redis
# 使用 BY pattern 参数,根据 user_level_uid 的值来排序
redis> SORT uid BY user_level_*
1) "2"
2) "3"
3) "4"
4) "1"
user_level_*
是一个占位符,它先取出 uid
中的值,然后再用这个值来查找相应的键。
比如在对 uid
列表进行排序时,程序就会先取出 uid
的值 1、2、3、4,然后使用 user_level_1
、user_level_2
、user_level_3
和 user_level_4
的值作为排序 uid
的权重。
GET 选项
redis
# 使用 GET pattern 参数,获取 user_name_uid 的值,并返回排序结果
redis> SORT uid BY user_level_* GET user_name_*
1) "jack"
2) "peter"
3) "mary"
4) "admin"
BY 和 GET 选项组合使用
redis
# 使用 BY 和 GET 选项,同时获取 user_name_{uid} 和 user_level_{uid} 的值,并返回排序结果
redis> SORT uid BY user_level_* GET user_name_* GET user_level_*
1) "jack"
2) "10"
3) "peter"
4) "25"
5) "mary"
6) "70"
7) "admin"
8) "9999"
GET
有一个额外的参数规则,那就是------可以用 #
获取被排序键的值。
以下代码就将 uid
的值、及其相应的 user_level_*
和 user_name_*
都返回为结果:
redis
redis> SORT uid GET # GET user_level_* GET user_name_*
1) "2"
2) "10"
3) "jack"
4) "3"
5) "25"
6) "peter"
7) "4"
8) "70"
9) "mary"
10) "1"
11) "9999"
12) "admin"
获取外部键,但不进行排序
在某些情况下,你可能希望获取一个键的值,但不将其用于排序。在这种情况下,通过将一个不存在的键作为参数传给 BY
选项,可以让 SORT
跳过排序操作,直接返回结果:
redis
redis> SORT uid BY not-exists-key
1) "4"
2) "3"
3) "2"
4) "1"
这种用法在单独使用时,没什么实际用处。不过,通过将这种用法和 GET
选项配合,就可以在不排序的情况下,获取多个外部键,相当于执行一个整合的获取操作(类似于 SQL 数据库的 join
关键字)。
将哈希表作为 GET
或 BY
的参数
redis
HMSET user_info_1 name admin level 9999
HMSET user_info_2 name jack level 10
HMSET user_info_3 name peter level 25
HMSET user_info_4 name mary level 70
redis
redis> SORT uid BY user_info_*->level
1) "2"
2) "3"
3) "4"
4) "1"
redis> SORT uid BY user_info_*->level GET user_info_*->name
1) "jack"
2) "peter"
3) "mary"
4) "admin"
保存排序结果
默认情况下,SORT
操作只是简单地返回排序结果,并不进行任何保存操作。通过给 STORE
选项指定一个 key
参数,可以将排序结果保存到给定的键上。如果被指定的 key
已存在,那么原有的值将被排序结果覆盖。
redis
# 测试数据
redis> RPUSH numbers 1 3 5 7 9
(integer) 5
redis> RPUSH numbers 2 4 6 8 10
(integer) 10
redis> LRANGE numbers 0 -1
1) "1"
2) "3"
3) "5"
4) "7"
5) "9"
6) "2"
7) "4"
8) "6"
9) "8"
10) "10"
redis> SORT numbers STORE sorted-numbers
(integer) 10
# 排序后的结果
redis> LRANGE sorted-numbers 0 -1
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "6"
7) "7"
8) "8"
9) "9"
10) "10"
可以通过将 SORT
命令的执行结果保存,并用 EXPIRE
为结果设置生存时间,以此来产生一个 SORT
操作的结果缓存。这样就可以避免对 SORT
操作的频繁调用:只有当结果集过期时,才需要再调用一次 SORT
操作。
另外,为了正确实现这一用法,你可能需要加锁以避免多个客户端同时进行缓存重建(也就是多个客户端,同一时间进行 SORT
操作,并保存为结果集),具体参见 SETNX
命令。