Redis-数据类型的常用命令
前言
一、字符串
Redis中最基本的数据类型
key-value ,value最大512M…
key区分大小写,value 可以是字符串、数字或二进制数据
help @string
1.1 set
set key value [NX|XX] [GET] [EX seconds|PX milliseconds|EXAT unix-time-seconds|PXAT unix-time-milliseconds|KEEPTTL]
set/get 设置和获取值
127.0.0.1:6379> set key1 v1
OK
127.0.0.1:6379> get key1
"v1"
127.0.0.1:6379> set key1 v2
OK
127.0.0.1:6379> get key1
"v2"
1.1.1 NX
键不存在,设置新值; 键存在,命令失效
127.0.0.1:6379> set key1 v3 nx
(nil)
127.0.0.1:6379> get key1
"v2"
127.0.0.1:6379> set key3 v3 nx
OK
127.0.0.1:6379> keys *
1) "key1"
2) "key3"
1.1.2 XX
键存在,设置新值;键不存在,不会创建新的key
127.0.0.1:6379> set key1 v3 xx
OK
127.0.0.1:6379> get key1
"v3"
127.0.0.1:6379> set key2 v3 xx
(nil)
127.0.0.1:6379> keys *
1) "key1"
1.1.3 GET
返回原本的值
127.0.0.1:6379> set key1 v4 get
"v3"
127.0.0.1:6379> get key1
"v4"
127.0.0.1:6379> getset key1 v5
"v4"
127.0.0.1:6379> get key1
"v5"
1.1.4 EX、PX、EXAT、PXAT、KEEPTTL
- EX seconds: 以
秒
为单位设置过期时间 - PX milliseconds: 以
毫秒
为单位设置过期时间 - EXAT unix-time-seconds: 以
秒
为单位的UNIX时间戳
为单位设置过期时间 - PXAT unix-time-milliseconds:以
毫秒
为单位的UNIX时间戳
为单位设置过期时间 - KEEPTTL: 保留之前设置的生存时间
ttl: -1永久有效,-2已经失效,n n秒后过期
127.0.0.1:6379> set Tkey1 v1 ex 30
OK
127.0.0.1:6379> ttl Tkey1
(integer) 26
查看时间戳
[root@db ~]# date +%s
1756432957
127.0.0.1:6379> set Tkey2 v1 exat 1756432957
OK
127.0.0.1:6379> ttl Tkey2
(integer) 55
默认覆盖过期时间
127.0.0.1:6379> set Tkey1 v1 ex 500
OK
127.0.0.1:6379> get Tkey1
"v1"
127.0.0.1:6379> ttl Tkey1
(integer) 490
127.0.0.1:6379> set Tkey1 v2
OK
127.0.0.1:6379> ttl Tkey1
(integer) -1
keepttl参数保留过期时间
127.0.0.1:6379> set Tkey1 v1 ex 500
OK
127.0.0.1:6379> ttl Tkey1
(integer) 497
127.0.0.1:6379> set Tkey1 v2 keepttl
OK
127.0.0.1:6379> ttl Tkey1
(integer) 486
1.2 mset、mget、msetnx
mset/mget
批量赋值与取值
127.0.0.1:6379> mset k1 v1 k2 v2
OK
127.0.0.1:6379> mget k1 k2
1) "v1"
2) "v2"
msetnx
批量设置多个键值对,但仅当所有键都不存在时才会执行成功,只要有一个键已存在,整个操作就会失败(原子性操作)
127.0.0.1:6379> msetnx k1 v3 k4 v1
(integer) 0
127.0.0.1:6379> keys *
1) "k1"
2) "Tkey1"
3) "key1"
4) "key3"
5) "k2"
127.0.0.1:6379> get k1
"v1"
1.3 getrange、setrange
getrange
获取指定区间值
127.0.0.1:6379> get k1
"abcd1234"
127.0.0.1:6379> getrange k1 0 -1
"abcd1234"
127.0.0.1:6379> getrange k1 0 3
"abcd"
setrange
修改指定区间的值
127.0.0.1:6379> setrange k1 2 xx
(integer) 8
127.0.0.1:6379> get k1
"abxx1234"
127.0.0.1:6379> setrange k1 2 xxxxxxxxxxxx
(integer) 14
127.0.0.1:6379> get k1
"abxxxxxxxxxxxx"
127.0.0.1:6379> get k2
"v2"
127.0.0.1:6379> setrange k2 -1 xx
(error) ERR offset is out of range
127.0.0.1:6379> setrange k2 2 xx
(integer) 4
127.0.0.1:6379> get k2
"v2xx"
1.4 strlen、append
strlen
获取值的长度
127.0.0.1:6379> strlen k1
(integer) 14
append
向值后追加字符串
127.0.0.1:6379> append k1 abcd
(integer) 18
127.0.0.1:6379> get k1
"abxxxxxxxxxxxxabcd"
127.0.0.1:6379> strlen k1
(integer) 18
1.5 incr、incrby、decr、decrby
数值的增加
incr k1
+1
incrby k1 n
+n
127.0.0.1:6379> set k1 10
OK
127.0.0.1:6379> incr key
(integer) 1
127.0.0.1:6379> get k1
"11"
127.0.0.1:6379> incrby k1 10
(integer) 21
127.0.0.1:6379> get k1
"21"
数值的减少
decr k1
-1
decrby k1 n
-n
127.0.0.1:6379> decrby k1 10
(integer) 11
127.0.0.1:6379> get k1
"11"
127.0.0.1:6379> decr k1
(integer) 10
127.0.0.1:6379> get k1
"10"
1.6 应用场景
- 发送验证码
验证码登录(临时存储-快) - 浏览量
看+1, 点赞+1
二、列表
是简单的字符串列表,可以从最左或最右进行插入/删除的操作
底层实际上是一个双端链表,最多可以包含40多亿个元素
push, pop
一般用在栈、队列场景
操作: key不存在 => 创建一个新链表
key已在在 => 往链表中添加内容
如果value值全部移除 => 对应key也就消失了
list => 对两端操作性能高,而对索引中间节点性能差
help @list
2.1 lpush、lrange、rpush、lindex
lpush/lrange
插入数据和查看所有数据
127.0.0.1:6379> lpush lk1 1 2 3 4
(integer) 4
127.0.0.1:6379> lrange lk1 0 -1
1) "4"
2) "3"
3) "2"
4) "1"
127.0.0.1:6379> rpush lk1 5 6 7 8
(integer) 8
127.0.0.1:6379> lrange lk1 0 -1
1) "4"
2) "3"
3) "2"
4) "1"
5) "5"
6) "6"
7) "7"
8) "8"
lindex
查看指定位置的数据
127.0.0.1:6379> lindex lk1 5
"6"
127.0.0.1:6379> lindex lk1 0
"4"
2.2 lpop、rpop、lrem
lpop/rpop
删除左侧/右侧第一个数据
127.0.0.1:6379> lpop lk1
"4"
127.0.0.1:6379> lrange lk1 0 -1
1) "3"
2) "2"
3) "1"
4) "5"
5) "6"
6) "7"
7) "8"
127.0.0.1:6379> rpop lk1
"8"
127.0.0.1:6379> lrange lk1 0 -1
1) "3"
2) "2"
3) "1"
4) "5"
5) "6"
6) "7"
lrem
根据元素值来移除数据
# 移除lk1中3个5
127.0.0.1:6379> lrem lk1 3 5
(integer) 1
127.0.0.1:6379> lrange lk1 0 -1
1) "3"
2) "2"
3) "1"
4) "6"
5) "7"
127.0.0.1:6379> lpush lk1 1 1 1 1 1
(integer) 10
127.0.0.1:6379> lrange lk1 0 -1
1) "1"
2) "1"
3) "1"
4) "1"
5) "1"
6) "3"
7) "2"
8) "1"
9) "6"
10) "7"
# 移除lk1中3个1
127.0.0.1:6379> lrem lk1 3 1
(integer) 3
127.0.0.1:6379> lrange lk1 0 -1
1) "1"
2) "1"
3) "3"
4) "2"
5) "1"
6) "6"
7) "7"
2.3 rpoplpush、lrtim
rpoplpush
移除列表中最后一个元素,将它追加到另一个列表中
127.0.0.1:6379> lpush lk3 1 2 3 4
(integer) 4
127.0.0.1:6379> lpush lk4 a b c d
(integer) 4
127.0.0.1:6379> rpoplpush lk3 lk4
"1"
127.0.0.1:6379> lrange lk3 0 -1
1) "4"
2) "3"
3) "2"
127.0.0.1:6379> lrange lk4 0 -1
1) "1"
2) "d"
3) "c"
4) "b"
5) "a"
ltrim
截取列表,截取后会删除其他元素
127.0.0.1:6379> lrange lk4 0 -1
1) "1"
2) "d"
3) "c"
4) "b"
5) "a"
127.0.0.1:6379> ltrim lk4 1 3
OK
127.0.0.1:6379> lrange lk4 0 -1
1) "d"
2) "c"
3) "b"
2.4 lset、linsert
lset
修改元素值
127.0.0.1:6379> lrange lk4 0 -1
1) "d"
2) "c"
3) "b"
127.0.0.1:6379> lset lk4 1 cc
OK
127.0.0.1:6379> lrange lk4 0 -1
1) "d"
2) "cc"
3) "b"
指定位置插入元素
linsert after/before
127.0.0.1:6379> lrange lk4 0 -1
1) "d"
2) "cc"
3) "b"
127.0.0.1:6379> linsert lk4 after cc c1
(integer) 4
127.0.0.1:6379> lrange lk4 0 -1
1) "d"
2) "cc"
3) "c1"
4) "b"
127.0.0.1:6379> linsert lk4 before cc c0
(integer) 5
127.0.0.1:6379> lrange lk4 0 -1
1) "d"
2) "c0"
3) "cc"
4) "c1"
5) "b"
2.5 应用场景
粉丝推送
flask -> 视频网站B站 -> 关注关注关系 => MySQL
CiCi <= A,B,C,D,E,F 千万粉丝
Cali <= A,B,G
直接操作 MySQL 会因数据量大导致阻塞,而 Redis 列表的两端高效操作和异步处理特性可以完美解决- 发布视频时:
在 MySQL 中记录视频信息
异步任务将所有粉丝 ID 批量写入 Redis 列表(作为消息队列) - 推送任务:
独立的后台程序从列表中逐个弹出粉丝 ID
调用推送接口(如站内信、APP 推送)发送通知
- 发布视频时:
定时任务:生成周报、生成月报
定时任务 => 在Redis中生成一个列表
后台程序 => 读取在Redis中生成一个列表 =>
三、哈希
相当于Python中字典
key : (key-value)
哈希表是一个string类型的key:value映射表
每个hash可以存储40多亿个键值对
help @hash
3.1 hset、hget、hmget、hgetall
hset/hget
数据存取
127.0.0.1:6379> hset user:cici id 1
(integer) 1
127.0.0.1:6379> hset user:cici name cici
(integer) 1
127.0.0.1:6379> hset user:cici age 18
(integer) 1
127.0.0.1:6379> type user:cici
hash
# hlen:查看字段数量
127.0.0.1:6379> hlen user:cici
(integer) 3
127.0.0.1:6379> hset user:cici yuwen 100 shuxue 100
(integer) 2
127.0.0.1:6379> hget user:cici id
"1"
# 获取多个字段的值
127.0.0.1:6379> hmget user:cici id name
1) "1"
2) "cici"
# 获取所有字段和值
127.0.0.1:6379> hgetall user:cici
1) "id"
2) "1"
3) "name"
4) "cici"
5) "age"
6) "18"
7) "yuwen"
8) "100"
9) "shuxue"
10) "100"
3.2 hkeys、hvals
获取所有key或value
127.0.0.1:6379> hkeys user:cici
1) "id"
2) "name"
3) "age"
4) "yuwen"
5) "shuxue"
127.0.0.1:6379> hvals user:cici
1) "1"
2) "cici"
3) "18"
4) "100"
5) "100"
3.3 hdel、hsetnx、hexists、hincrby
hdel
删除数据
127.0.0.1:6379> hdel user:cici yuwen shuxue
(integer) 2
127.0.0.1:6379> hgetall user:cici
1) "id"
2) "1"
3) "name"
4) "cici"
5) "age"
6) "18"
hset
数据修改(设置)
127.0.0.1:6379> hset user:cici id 2
(integer) 0
127.0.0.1:6379> hgetall user:cici
1) "id"
2) "2"
3) "name"
4) "cici"
5) "age"
6) "18"
hsetnx
已经存在Key时不修改,key不存在时添加
127.0.0.1:6379> hsetnx user:cici id 3
(integer) 0
127.0.0.1:6379> hgetall user:cici
1) "id"
2) "2"
3) "name"
4) "cici"
5) "age"
6) "18"
127.0.0.1:6379> hsetnx user:cici id2 3
(integer) 1
127.0.0.1:6379> hgetall user:cici
1) "id"
2) "2"
3) "name"
4) "cici"
5) "age"
6) "18"
7) "id2"
8) "3"
hexists
判断key是否存在,存在1,不存在0
127.0.0.1:6379> hexists user:cici id
(integer) 1
127.0.0.1:6379> hexists user:cici id2
(integer) 1
127.0.0.1:6379> hexists user:cici id3
(integer) 0
hincrby
数据值的增减
127.0.0.1:6379> hincrby user:cici id -1
(integer) 1
127.0.0.1:6379> hget user:cici id
"1"
127.0.0.1:6379> hincrby user:cici id 10
(integer) 11
127.0.0.1:6379> hget user:cici id
"11"
3.4 应用场景 key:value
购物车 => 存储下来
MySQL数据库
cart
id, 用户id, 商品id, 数量(如果购物车有10个商品,这里就有10条数据)
苹果 1
西瓜 2
数据库数据量大、修改频繁
id, 用户id, 详情(json字符串{“苹果id”:1, “西瓜”:2})Redis(高效-内存型)
hset cart:uid001 苹果 1 西瓜 2
hincrby cart:uid001 苹果 +1
hlen cart:uid001
hgetall cart:uid001
四、集合
类似于列表,集合不能包含重复值
,无顺序
(不会按写入的顺序排序)
集合操作 -> 并集、交集、差集
集合是通过哈表实现的,每个集合可以存储40多亿个数据
2^32-1
help @set
4.1 sadd、smembers、scard
sadd
创建集合
127.0.0.1:6379> sadd numlist 1 1 2 3 4 7 5 3 2 9 8 6
(integer) 9
127.0.0.1:6379> type numlist
set
smembers
获取所有元素
127.0.0.1:6379> smembers numlist
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "6"
7) "7"
8) "8"
9) "9"
scard
获取元素数量
127.0.0.1:6379> sadd numlist d e a c f k
(integer) 6
127.0.0.1:6379> scard numlist
(integer) 15
4.2 srandmember、sismember
srandmember
随机从集合中取出3个元素
127.0.0.1:6379> srandmember numlist 3
1) "1"
2) "7"
3) "8"
sismember
判断集合中是否存在某个元素,1 存在 ,0 不存在
127.0.0.1:6379> sismember numlist a
(integer) 1
127.0.0.1:6379> sismember numlist aa
(integer) 0
4.3 srem、spop、smove
srem
删除元素
127.0.0.1:6379> srem numlist a 1
(integer) 2
127.0.0.1:6379> scard numlist
(integer) 13
127.0.0.1:6379> smembers numlist
1) "2"
2) "3"
3) "4"
4) "5"
5) "6"
6) "7"
7) "8"
8) "9"
9) "d"
10) "e"
11) "c"
12) "f"
13) "k"
spop
随机删除
127.0.0.1:6379>spop numlist 4
127.0.0.1:6379> smembers numlist
1) "3"
2) "4"
3) "5"
4) "7"
5) "8"
6) "9"
7) "e"
8) "f"
9) "k"
smove
移动元素
127.0.0.1:6379> sadd numlist1 a b c
(integer) 3
127.0.0.1:6379> smove numlist numlist1 3
(integer) 1
127.0.0.1:6379> smembers numlist1
1) "a"
2) "b"
3) "c"
4) "3"
4.4 sdiff、sunion、sinter
集合运算
127.0.0.1:6379> sadd set1 a b c 1 2
(integer) 5
127.0.0.1:6379> sadd set2 b c 1 3
(integer) 4
差集:sdiff
A - B 返回A存在且B中不存在的元素
127.0.0.1:6379> sdiff set1 set2
1) "a"
2) "2"
127.0.0.1:6379> sdiff set2 set1
1) "3"
并集:sunion
A U B 返回A和B中的所有元素,去重
127.0.0.1:6379> sunion set1 set2
1) "a"
2) "b"
3) "3"
4) "2"
5) "c"
6) "1"
交集:sinter
A ∩ B 返回A和B中都存在的元素
127.0.0.1:6379> sinter set1 set2
1) "b"
2) "c"
3) "1"
4.5 应用场景
抽奖
奖品x3
用户:点击参加
sadd huodong:001 userid
显示参加人数
scard huodong:001
抽奖(定时抽奖) => huodong:001:result
srandmember huodong:001 3
spop huodong:001 3
用户点击
huodong:001:result
sismember huodong:001:result a社交: QQ共同群,共同好友,朋友圈点赞,可能认识的人
MySQL => 程序(python) => 处理Redis
sadd friends:cici user1 user2 user3 user4 user5 …
sadd friends:cjj user4 user5 user6 user7 user8 …friends:cici ∩ friends:cjj => 所有的共同好友 => len
五、有序集合 ZSET
zset和set都是string类型的集合
区别:zset会关联一个double类型的分数,根据分数进行从小到大的排序
成员不能重复,但分数可以重复
场景:排序场景
5.1 zadd、zscore、zcard、zcount
zadd
添加元素及分数
如果有重复的数据,分数以后面的数据为准
127.0.0.1:6379> zadd zset1 10 a 20 b 8 c 10 c
(integer) 0
127.0.0.1:6379> zscore zset1 c
"10"
zscore
获取元素分数
127.0.0.1:6379> zscore zset1 c
"10"
zcard
获取元素数量
127.0.0.1:6379> zcard zset1
(integer) 3
zcount
获取指定范围的元数个数
127.0.0.1:6379> zadd zset1 8 d
(integer) 1
127.0.0.1:6379> zcount zset1 8 10
(integer) 3
127.0.0.1:6379> zadd zset1 9 e
(integer) 1
127.0.0.1:6379> zcount zset1 8 10
(integer) 4
5.2 z(rev)rank、z(rev)range、zrangebyscore
zrank
获取元素下标 => (排名) => 下标从0开始
127.0.0.1:6379> zrank zset1 a
(integer) 2
127.0.0.1:6379> zrank zset1 b
(integer) 4
127.0.0.1:6379> zrank zset1 c
(integer) 3
127.0.0.1:6379> zrank zset1 d
(integer) 0
127.0.0.1:6379> zrank zset1 e
(integer) 1
zrevrank
逆序获取元素下标 => (排名)
127.0.0.1:6379> zrevrank zset1 a
(integer) 2
127.0.0.1:6379> zrevrank zset1 b
(integer) 0
127.0.0.1:6379> zrevrank zset1 c
(integer) 1
zrange
按下标查看元素
127.0.0.1:6379> zrange zset1 0 -1
1) "d"
2) "e"
3) "a"
4) "c"
5) "b"
# 查看元素及分数
127.0.0.1:6379> zrange zset1 0 -1 withscores
1) "d"
2) "8"
3) "e"
4) "9"
5) "a"
6) "10"
7) "c"
8) "10"
9) "b"
10) "20"
zrevrange
逆序查看元素带分数
127.0.0.1:6379> zrevrange zset1 0 -1 withscores
1) "b"
2) "20"
3) "c"
4) "10"
5) "a"
6) "10"
7) "e"
8) "9"
9) "d"
10) "8"
zrangebyscore
筛选分数在8-10的数据
127.0.0.1:6379> zrangebyscore zset1 8 10 withscores
1) "d"
2) "8"
3) "e"
4) "9"
5) "a"
6) "10"
7) "c"
8) "10"
# 筛选分数在8-10的数据(不包含8,不包含10)
127.0.0.1:6379> zrangebyscore zset1 (8 (10 withscores
1) "e"
2) "9"
5.3 zrem、zincrby
zrem
删除数据
127.0.0.1:6379> zrem zset a
(integer) 0
127.0.0.1:6379> zrange zset1 0 -1
1) "d"
2) "e"
3) "a"
4) "c"
5) "b"
127.0.0.1:6379> zrange zset1 0 -1 withscores
1) "d"
2) "8"
3) "e"
4) "9"
5) "a"
6) "10"
7) "c"
8) "10"
9) "b"
10) "20"
zincrby
分数的增减
视频被点击一次
127.0.0.1:6379> zincrby zset1 1 b
"21"
127.0.0.1:6379> zincrby zset1 -10 b
"11"
5.4 应用场景
涉及计数、排序
MySQL
id , topicname, scoresRedis
热门话题排行榜
有4个热门话题
zadd topics:sort 0 topic1 10 topic2 45 topic3 33 topic4
有人搜索创建话题
zadd topics:sort 1 topic5
又有10个人搜索了topic1, 5个人搜索了topic2
127.0.0.1:6379> zincrby topics:sort 10 topic1
“10”
127.0.0.1:6379> zincrby topics:sort 5 topic2
“15”
查看排名前3的话题及查询量127.0.0.1:6379> zrevrange topics:sort 0 2 withscores 1) "topic3" 2) "45" 3) "topic4" 4) "33" 5) "topic2" 6) "15"
六、地理空间 GEO
移动端,附近的xxx(人/自行车/商店…)
地球上地理位置是二维经纬度表示
功能:
- 添加地理位置
- 获取地理位置
- 计算两个位置的距离
- 根据用户给定的坐标来获取指定范围内的地理位置集合
百度地图-坐标拾取器:https://lbs.baidu.com/maptool/getpoint
6.1 geadd、zrange
设置位置
geadd key 经度 维度 位置名称 [经度 维度 位置名称 ....]
127.0.0.1:6379> geoadd city-bj 116.40 39.91 "天安门"
(integer) 1
127.0.0.1:6379> geoadd city-bj 116.40 40.00 "国家体育馆"
(integer) 1
127.0.0.1:6379> geoadd city-bj 116.33 39.90 "北京西站"
(integer) 1
127.0.0.1:6379> type city-bj
zset
GEO底层是有序集合,所以可以通过zrange命令获取GEO的元素数据
127.0.0.1:6379> zrange city-bj 0 -1
1) "\xe5\x8c\x97\xe4\xba\xac\xe8\xa5\xbf\xe7\xab\x99"
2) "\xe5\xa4\xa9\xe5\xae\x89\xe9\x97\xa8"
3) "\xe5\x9b\xbd\xe5\xae\xb6\xe4\xbd\x93\xe8\x82\xb2\xe7\xe9\xa6\x86"
中文信息默认会显示成字节码形式,可以用–raw连接客户端
[root@db ~]# redis-cli --raw
127.0.0.1:6379> zrange city-bj 0 -1
北京西站
天安门
国家体育馆
6.2 geopos、geohash、geodist、georadius
geopos
获取指定位置的经纬度
127.0.0.1:6379> geopos city-bj 天安门 北京西站
116.39999896287918
39.90999956664451
116.32999867200851
39.900000091670925
geohash
获取指定位置的经纬度的hash串
127.0.0.1:6379> geohash city-bj 天安门 北京西站
wx4g09ruse0
wx4dzpsfm70
地理距离
geodist key 位置名 位置名 距离单位(m/km/ft/mi)
127.0.0.1:6379> geodist city-bj 天安门 北京西站 km
6.0753
127.0.0.1:6379> geodist city-bj 天安门 北京西站 km
6.0753
127.0.0.1:6379> geodist city-bj 天安门 北京西站 m
6075.2881
计算某个位置、某个经纬度 xx范围的地理位置信息
georadius key 经纬度 最大距离 距离单位 withdist withcoord count N desc
georadiusbymember key 位置名 最大距离 距离单位 withdist withcoord count N desc
- withdist: 返回位置元素的同时,将位置元素与中心之间距离也返回
- withcoord: 返回位置元素的同时,将位置元素的经纬度返回
- withhash: 返回位置元素的同时,将位置元素的hash返回
127.0.0.1:6379> georadius city-bj 116.38 39.93 10 km withdist withcoord withhash count 10 desc
国家体育馆
7.9703
4069886622955888
116.39999896287918
39.99999991084916
127.0.0.1:6379> georadiusbymember city-bj 天安门 20 km withdist withcoord withhash count 10 desc
国家体育馆
10.0104
4069886622955888
116.39999896287918
39.99999991084916
北京西站
6.0753
4069879554635914
116.32999867200851
39.900000091670925
天安门
0.0000
4069885544737889
116.39999896287918
39.90999956664451