Redis-数据类型

关于数据类型

Redis中用的最多的数据类型有String、Hash、List、Set、Zset。
而Redis的key都是字符串,不同的数据类型指的是value的类型

key的通用操作

在Redis中的终端中,一般命令无大小写之分,也可以使用tab键补全和切换命令

1 127.0.0.1:6379> keys *             # 返回所有的key,尽量避免在生产中使用
2 127.0.0.1:6379> keys k*            # 可以用模糊匹配来替代 keys *
3 127.0.0.1:6379> keys k1            # 返回k1
4 127.0.0.1:6379> type k1            # 返回k1的value类型
5 127.0.0.1:6379> DEL k2             # 删除一个key
6 127.0.0.1:6379> EXISTS k2          # 判断 key 是否存在
7 127.0.0.1:6379> RENAME k3 k33      # 重命名

设置键值对的生存时间:

 1 # EXPIRE/PEXPIRE       以秒/毫秒为单位设置生存时间
 2 # TTL/PTTL             以秒/毫秒为单位返回剩余的生存时间
 3 # PERSIST              即在生存时间内,取消生存时间设置
 4 
 5 127.0.0.1:6379> EXPIRE k2 20         # 为 k2 设置生存时间为20秒
 6 (integer) 1
 7 127.0.0.1:6379> ttl k2               # 返回 k2 剩余的生存时间
 8 (integer) 15
 9 127.0.0.1:6379> PERSIST k2           # 取消生存时间设置
10 (integer) 1
11 127.0.0.1:6379> ttl k2               # 表示没有设置生存时间
12 (integer) -1

注意,不要将大量的键值对设置为同一时间失效,避免造成缓存雪崩!

string

应用场景:

  • session 共享
  • 常规计数:评论数、粉丝数、礼物数、订阅数

字符串的相关操作

 1 # 如果key存在,则覆盖原来的value值,若key不存在,就设置key和value
 2 127.0.0.1:6379> set hello world
 3 OK
 4 127.0.0.1:6379> get hello
 5 "world"
 6 
 7 # 先get再set
 8 127.0.0.1:6379> getset k1 v1   # 先get,因为k1不存在,返回空nil,然后在设置一个值v1
 9 (nil)
10 127.0.0.1:6379> get k1   # 可以看到设置成功了
11 "v1"
12 127.0.0.1:6379> getset k1 v2  # 先get,获取到的值是上一次的结果,再set一个新值
13 "v1"
14 127.0.0.1:6379> get k1  # 最新值
15 "v2"
16 
17 # 在set的时候指定存活时间,在存活时间内,可以获取到该值
18 127.0.0.1:6379> setex k2 10  v2
19 OK
20 127.0.0.1:6379> ttl k2
21 (integer) 6
22 127.0.0.1:6379> get k2
23 "v2"
24 127.0.0.1:6379> get k2
25 (nil)
26 
27 # 如果key不存在,就设置一个key:value,如果key存在则什么都不做
28 127.0.0.1:6379> setnx k3 v3
29 (integer) 1
30 127.0.0.1:6379> get k3
31 "v3"
32 127.0.0.1:6379> setnx k3 v33
33 (integer) 0
34 127.0.0.1:6379> get k3
35 "v3"
36 
37 # 批量设置和批量获取
38 127.0.0.1:6379> mset k4 v4 k5 v5 k6 v6
39 OK
40 127.0.0.1:6379> mget k4 k5 k6
41 1) "v4"
42 2) "v5"
43 3) "v6"
44 
45 
46 # 删除key
47 127.0.0.1:6379> del k1
48 (integer) 1
49 
50 # 追加值,若key不存在,相当于add,若key存在,就是相当于拼接字符串
51 127.0.0.1:6379> get k5   # k5存在
52 "v5"
53 127.0.0.1:6379> append k5 5  # 因为k5存在,所以拼接字符串,并返回拼接后的字符串长度
54 (integer) 3
55 127.0.0.1:6379> get k5  # 拼接后的value
56 "v55"
57 127.0.0.1:6379> del k5
58 (integer) 1
59 127.0.0.1:6379> append k5 5   # k5不存在,相当于添加一个key:value 并返回value的长度
60 (integer) 1
61 127.0.0.1:6379> get k5  # 添加后的值
62 "5"
63 
64 # 为指定字节位置的元素替换为指定值
65 127.0.0.1:6379> set k7 0123456789
66 127.0.0.1:6379> setrange k7 5 A   # 将第5个字节位置的值替换为 A
67 (integer) 10
68 127.0.0.1:6379> get k7  # 替换后的结果
69 "01234A6789"
70 127.0.0.1:6379> setrange k7 12 BC  # 如果指定的字节数超出字符串长度,就补零
71 (integer) 14
72 127.0.0.1:6379> get k7 
73 "01234A6789\x00\x00BC"
74 127.0.0.1:6379> setrange k7 6 7 BC   # 不允许这种将第6~7字节位置的元素替换为指定值
75 (error) ERR wrong number of arguments for 'setrange' command
76 
77 # 判断key是否存在,存在返回1,否则返回0
78 127.0.0.1:6379> EXISTS k1
79 (integer) 1
80 
81 # 如果key存在,返回值的长度,否则返回0
82 127.0.0.1:6379> get k1
83 "v2"
84 127.0.0.1:6379> STRLEN k1
85 (integer) 2
86 127.0.0.1:6379> STRLEN k222   # k222不存在
87 (integer) 0
88 
89 
90 # 返回字符串指定字节范围的值
91 127.0.0.1:6379> set k7 0123456789
92 OK
93 127.0.0.1:6379> GETRANGE k7 1 5   # 第1~5个字节范围内的值
94 "12345"
95 127.0.0.1:6379> GETRANGE k7 5 15  # 第5~15个字节范围内的值,如果字符串长度不够,以起始位置开始,有多少返回多少
96 "56789"
97 127.0.0.1:6379> GETRANGE k7 15 20  # 起始和结束范围都不在字符串范围内,返回空
98 ""

上例中有对范围设置值或者取值的操作,但谨记,不能对中文这么做,因为一个中文由多个字节组成。

计数器功能

127.0.0.1:6379> INCR num             # 每次调用incr命令,num值自加一
(integer) 1
127.0.0.1:6379> INCR num 
(integer) 2
127.0.0.1:6379> INCRBY num 1000      # 一次性累加指定数
(integer) 1002
127.0.0.1:6379> INCRBY num 1000
(integer) 2002
127.0.0.1:6379> INCR num
(integer) 2003
127.0.0.1:6379> DECR num             # decr 使num自减一
(integer) 2002
127.0.0.1:6379> DECR num
(integer) 2001
127.0.0.1:6379> DECRBY num 1000      # 一次性累减指定数
(integer) 1001
127.0.0.1:6379> DECRBY num 1000
(integer) 1
127.0.0.1:6379> get num              # 可以通过get获取该计数器的值
"1"

hash

应用场景:

  • 数据缓存

类似python的字典,但是成员只能是string,专门用于结构化的数据信息。

使用hmset来声明一个hash类型的一组或者多组键值对;使用hmget来获取一组或者多组键值对的值:

 1 # 增,若某字段存在,就更新其value,否则就是添加key:value
 2 127.0.0.1:6379> hmset user_1 id 1 name zhangkai age 18 gender m
 3 OK
 4 127.0.0.1:6379> hmset user_2 id 2 name wangkai age 20 gender m
 5 OK
 6 
 7 
 8 #
 9 127.0.0.1:6379> hget user_1 name                # 获取指定字段的值
10 127.0.0.1:6379> hmget user_1 id name age        # 获取多个字典的值
11 127.0.0.1:6379> hgetall user_1                  # 返回所有字段和值
12 127.0.0.1:6379> HKEYS user_1                    # 返回key中所有的字段
13 127.0.0.1:6379> HVALS user_1                    # 返回key中所有的字段值
14 127.0.0.1:6379> HEXISTS user_1 name             # 判断指定字段是否存在,存在返回1,否则返回0
15 127.0.0.1:6379> HLEN user_1                     # 返回key中所有字段的数量
16 
17 #
18 127.0.0.1:6379> HINCRBY user_1 age 1            # 为整型字段的值加固定数字
19 127.0.0.1:6379> hget user_1 age
20 127.0.0.1:6379> hset user_1 name zhangkai2      # 为指定字段重新赋值

list

应用场景:

  • 消息队列系统
  • 最新的微博消息,比如我们将最新发布的热点消息都存储到Redis中,只有翻看"历史久远"的个人信息,这类冷数据时,才去MySQL中查询

列表的特点:

  • 后插入的在最前面,相当于每次都默认在索引0前面做插入操作。这个特性相当于微信朋友圈,最新发布的的动态在最上面。
  • 列表内每一个元素都有自己的下标索引,从左到右,从0开始;从右到左,从-1开始,这跟Python中的列表一样。
  • 列表中的元素可重复。
 1 127.0.0.1:6379> LPUSH msg "message day1"
 2 (integer) 1
 3 127.0.0.1:6379> LPUSH msg "message day2"
 4 (integer) 2
 5 127.0.0.1:6379> LPUSH msg "message day3"
 6 (integer) 3
 7 127.0.0.1:6379> LPUSH msg "message day4"
 8 (integer) 4
 9 127.0.0.1:6379> LRANGE msg 0 -1
10 1) "message day4"
11 2) "message day3"
12 3) "message day2"
13 4) "message day1"

来看操作:

 1 #
 2 LPUSH l1 a b                         # 如果 l1 不存在就创建,然后将 a b 插入到 l1 中,如果 l1 存在,直接将 a b 插入到 l1 中
 3 LPUSHX l1 c                          # 如果 key 存在则插入,不存在则什么也不做
 4 LINSERT l1 before a a1               # 在元素 a 前面插入 a1
 5 LINSERT l1 after a a2                # 在元素 a 后插入 a2
 6 RPUSH l1 1                           # 在列表尾部追加 元素 1
 7 RPUSH l1 2 3                         # 在列表尾部先追加 2 再追加 3
 8 RPUSHX l1 4                          # 如果列表 l1 存在就将元素4追加到列表尾部,如果列表不存在则什么也不做
 9 
10 # 查,根据索引下标取值
11 LRANGE l1 0 -1                       # 从索引0开始取到-1,也就是从头取到尾,获取列表中的所有元素
12 LRANGE l1 0 2                        # 取索引 0 1 2 三个索引对应的元素
13 LRANGE l1 0 0                        # 取索引 0 对应的元素
14 LRANGE l1 10 15                      # 如果索引不在合法范围内,则取空
15 LINDEX l1 1                          # 根据索引下标返回元素
16 
17 
18 # 删除
19 LPOP l1                              # 抛出列表头部元素
20 RPOP l1                              # 抛出列表尾部元素
21 RPOPLPUSH l1 l2                      # 将列表 l1 尾部的元素抛出并且添加到列表 l2 中
22 LREM l1 2 a1                         # 从左到右,删除指定个数的元素 a1 ,本示例中,若 a1 有 1 个,就删一个,若 a1  有 3 个或者更多,也就删除 2 个
23 LTRIM l1 2 4                         # 保留索引2-4的元素,其余删除
24 
25 #
26 LSET l1 0 a                          # 将列表索引为0的元素修改为指定值,如果索引位置不存在则报错

set#

集合的应用场景:

  • 适用于各种需要求交集、并集、差集的场景,比如共同好友,共同关注的场景。
  • 另外这里的集合也有数学上的集合特性,去重,交、并、差集的运算。

基础操作:

 1 # 增,声明key并添加 a b c 三个元素
 2 127.0.0.1:6379> sadd s1 a b c
 3 
 4 #
 5 127.0.0.1:6379> SMEMBERS s1         # 返回 s1 中所有元素
 6 127.0.0.1:6379> SCARD s1            # 返回 s1 中元素的个数
 7 127.0.0.1:6379> SRANDMEMBER s1      # 随机返回集合中的元素
 8 127.0.0.1:6379> SISMEMBER s1 a      # 判断元素 a 是否存在
 9 
10 # 删除
11 127.0.0.1:6379> SPOP s1             # 随机删除一个元素,并将这个元素返回
12 127.0.0.1:6379> del s1              # 删除 key 
13 
14 
15 # 移动
16 127.0.0.1:6379> smove s1 s2 a       # 将元素 a 从s1移动到s2中,如果s2不存在,就先创建再移动

再来看集合的运算。我们来个示例,有个需求,现有个培训学校欧德博爱开设了Python和Linux两门课程,来学习的同学都有如下情况:

  • 有的同学学习Linux
  • 有的学习Python
  • 还有的既学了Linux又学了Python

那现在问题来了,我们要对这些同学的情况做统计,比如找出两门课都报了的同学?

 

 

 1 # 先把数据准备好
 2 127.0.0.1:6379> SADD python xiaoA xiaoB Huluwa xiaoC xiaoMaque 
 3 (integer) 5
 4 127.0.0.1:6379> SADD linux xiaoC xiaoMaque xiaoD xiaoE xiaoDongbei
 5 (integer) 5
 6 
 7 # 求交集,找出即学习了Python又学习了Linux的同学
 8 127.0.0.1:6379> SINTER python linux
 9 1) "xiaoC"
10 2) "xiaoMaque"
11 # 求交集,找出即学习了Python又学习了Linux的同学,并将结果保存到集合tmp中,tmp不存在则先创建
12 127.0.0.1:6379> SINTERSTORE tmp python linux  
13 (integer) 2
14 127.0.0.1:6379> SMEMBERS tmp
15 1) "xiaoMaque"
16 2) "xiaoC"
17 
18 
19 # 求并集,找出学习两门课程的所有人
20 127.0.0.1:6379> SUNION python linux
21 1) "xiaoE"
22 2) "xiaoA"
23 3) "xiaoB"
24 4) "xiaoD"
25 5) "xiaoDongbei"
26 6) "xiaoMaque"
27 7) "xiaoC"
28 8) "Huluwa"
29 # 求并集,找出学习两门课程的所有人,并将结果保存到集合tmp中,tmp不存在则先创建
30 127.0.0.1:6379> SUNIONSTORE tmp python linux
31 (integer) 8
32 127.0.0.1:6379> SMEMBERS tmp
33 1) "xiaoE"
34 2) "xiaoA"
35 3) "xiaoB"
36 4) "xiaoD"
37 5) "xiaoDongbei"
38 6) "xiaoMaque"
39 7) "xiaoC"
40 8) "Huluwa"
41 
42 
43 # 求差集,找出只学习了Python(或者Linux)课程的人
44 127.0.0.1:6379> SDIFF python linux            # 只学习Python课程的人
45 1) "xiaoA"
46 2) "xiaoB"
47 3) "Huluwa"
48 127.0.0.1:6379> SDIFFSTORE tmp python linux # 只学习Python课程的人,并将结果保存到集合tmp中,tmp不存在则先创建
49 (integer) 3
50 127.0.0.1:6379> SMEMBERS tmp
51 1) "xiaoA"
52 2) "xiaoB"
53 3) "Huluwa"
54 
55 127.0.0.1:6379> SDIFF linux python            # 只学习Linux课程的人
56 1) "xiaoDongbei"
57 2) "xiaoE"
58 3) "xiaoD"
59 # # 只学习Linux课程的人,并将结果保存到集合tmp中,tmp不存在则先创建
60 127.0.0.1:6379> SDIFFSTORE tmp linux python
61 (integer) 3
62 127.0.0.1:6379> SMEMBERS tmp
63 1) "xiaoDongbei"
64 2) "xiaoE"
65 3) "xiaoD"

Zset#

有序集合在集合的基础上增加了排序功能,比如以点击数为条件进行排序。
有序集合的典型应用场景:

  • 各种排行榜,音乐排行榜、热点新闻榜.....

在有序集合中,我们一般称其元素为成员,其成员对应的值为分数。

基础操作:

  1 # 增加
  2 127.0.0.1:6379> ZADD top 0 xuwei 0 zhoujielun
  3 (integer) 2
  4 
  5 # 查, withscores是可选参数,表示同时返回其成员和其得分
  6 127.0.0.1:6379> ZSCORE top xuwei                # 返回top中,指定成员的分数,如果指定成员不存在则返回nil
  7 "0"
  8 127.0.0.1:6379> ZSCORE top zhangkai          
  9 (nil)
 10 
 11 # 返回top中所有成员,默认以分数大小升序排序,分值相同按ASCII编码排序
 12 127.0.0.1:6379> ZRANGE top 0 -1
 13 1) "xuwei"
 14 2) "zhoujielun"
 15 127.0.0.1:6379> ZRANGE top 0 -1 WITHSCORES
 16 1) "xuwei"
 17 2) "0"
 18 3) "zhoujielun"
 19 4) "0"
 20 
 21 # 返回成员在有序集合中的索引下标,如果成员不存在返回nil    
 22 127.0.0.1:6379> ZRANK top xuwei
 23 (integer) 0
 24 127.0.0.1:6379> ZRANK top zhangkai
 25 (nil)
 26 
 27 # 返回top中成员的数量
 28 127.0.0.1:6379> ZCARD top
 29 (integer) 2
 30 
 31 # 返回topN中所有成员,-inf表示第一个成员,+inf表示最后一个成员,结果默认以其分数的大小排序
 32 127.0.0.1:6379> ZRANGEBYSCORE top -inf +inf
 33 1) "xuwei"
 34 2) "zhoujielun"
 35 127.0.0.1:6379> ZRANGEBYSCORE top -inf +inf WITHSCORES
 36 1) "xuwei"
 37 2) "0"
 38 3) "zhoujielun"
 39 4) "0"
 40 
 41 # 返回topN中所有成员,并且以索引从大到小排序
 42 127.0.0.1:6379> ZREVRANGE top 0 -1
 43 1) "zhoujielun"
 44 2) "xuwei"
 45 127.0.0.1:6379> ZREVRANGE top 0 -1 WITHSCORES
 46 1) "zhoujielun"
 47 2) "0"
 48 3) "xuwei"
 49 4) "0"
 50 
 51 # 返回topN中 0 <= index <= 2 索引范围内的成员,不在范围内返回空
 52 127.0.0.1:6379> ZREVRANGE top 0 2
 53 1) "zhoujielun"
 54 2) "xuwei"
 55 127.0.0.1:6379> ZREVRANGE top 0 2 WITHSCORES
 56 1) "zhoujielun"
 57 2) "0"
 58 3) "xuwei"
 59 4) "0"
 60 127.0.0.1:6379> ZREVRANGE top 3 5 WITHSCORES
 61 (empty list or set)
 62 
 63 # 返回topN中分数在 20 <= 分数 <= 200 这个范围内的成员的数量
 64 127.0.0.1:6379> ZADD top 20 xuwei 80 zhoujielun 100 daolang 120 zhaolei   # 先搞个数据
 65 127.0.0.1:6379> ZCOUNT top 20 200
 66 (integer) 4
 67 
 68 # 返回topN中分数在 20 <= 分数 <= 200 这个范围内的成员
 69 127.0.0.1:6379> ZRANGEBYSCORE top 20 200
 70 1) "xuwei"
 71 2) "zhoujielun"
 72 3) "daolang"
 73 4) "zhaolei"
 74 127.0.0.1:6379> ZRANGEBYSCORE top 20 200 WITHSCORES
 75 1) "xuwei"
 76 2) "20"
 77 3) "zhoujielun"
 78 4) "80"
 79 5) "daolang"
 80 6) "100"
 81 7) "zhaolei"
 82 8) "120"
 83 
 84 # 返回topN中分数范围在 100 <= 的 <= 20 范围内的成员,并以的的大小降序排序
 85 127.0.0.1:6379> ZREVRANGEBYSCORE top 100 20
 86 1) "daolang"
 87 2) "zhoujielun"
 88 3) "xuwei"
 89 127.0.0.1:6379> ZREVRANGEBYSCORE top 100 20 WITHSCORES
 90 1) "daolang"
 91 2) "100"
 92 3) "zhoujielun"
 93 4) "80"
 94 5) "xuwei"
 95 6) "20"
 96 
 97 
 98 #
 99 # 为指定成员重新赋值
100 127.0.0.1:6379> ZADD top 30 xuwei
101 (integer) 0
102 
103 # 为指定成员增加指定分数,并返回增加后的分数
104 127.0.0.1:6379> ZINCRBY top 10 xuwei
105 "40"
106 
107 
108 # 删除
109 # 删除分数在指定范围内的成员,并返回删除成员的数量
110 127.0.0.1:6379> ZREMRANGEBYSCORE top 80 100
111 (integer) 2
112 
113 # 删除topN中指定索引范围内 0 <= index <= 1 的成员
114 127.0.0.1:6379> ZREMRANGEBYRANK top 0 1
115 (integer) 2
116 
117 # 删除topN中一个或者多个成员,返回实际删除的个数,没有找到key返回0
118 127.0.0.1:6379> ZREMRANGEBYRANK top 0 1
119 (integer) 2
120 
121 127.0.0.1:6379> DEL top
122 (integer) 1

来个音乐排行榜的示例:

 1 # 创建初始的音乐排行榜,初始每首歌播放量都是0
 2 ZADD top 0 aiqing 0 guxiang 0 lanlianhua 0 shiguang
 3 
 4 # 模拟每首歌的播放量
 5 ZINCRBY top 123 aiqing
 6 ZINCRBY top 223 guxiang
 7 ZINCRBY top 223 lanlianhua
 8 ZINCRBY top 23 shiguang
 9 
10 # 返回播放量前三名的歌名
11 127.0.0.1:6379> ZREVRANGE top 0 2 WITHSCORES
12 1) "aiqing"
13 2) "123"
14 3) "shiguang"
15 4) "0"
16 5) "lanlianhua"
17 6) "0"

 

posted @ 2023-09-05 17:18  软件改变思维!!  阅读(15)  评论(0)    收藏  举报