Redis(二)
本次博客主要介绍 Redis 的 value 最常见的五种数据结构,它们分别是:String、Hash、List、Set、Sorted Set
String
redis里面的String是以字节存储的,如果你的客户端是utf-8编码,那么上传上去的字符串就是按utf-8进行编码
redis的String里面除了存储数据以外,还存储了类型和长度。类型包括:字符串、数值以及bitmap
字符串
有最基本的6种操作,它们分别是:set、get、append、setrange、getrange、strlen
# 设置字符串,以下命令执行完毕之后,hello=world
set hello world
# 获取字符串,获取hello变量的值
get hello
# 追加字符串,以下命令执行完毕之后,hello=worldtest
append hello test
# 字符串修改某个位置开始的字符串,以下命令执行完毕之后,hello=tttldtest
setrange hello 0 ttt
# 字符串获取某个位置范围的字符串,以下命令执行完毕之后,输出 ttld
getrange hello 1 4
# 获取字符串长度,以下命令执行完毕,输出9
strlen hello
数值
redis可以将存储的字符串解析为一个数字,然后当做数值来进行处理,它只有一个操作incr
# 设置字符串
set test 9
# 使其加1,执行之后test变为10
incr test
数值类型,在抢购、秒杀、详情页、点赞、评论情况下使用,可以解决并发问题,对数据库的事务操作,完全有 redis 内存操作代替
bitmap
字符串是有一个个字节组成的,所以可以进行位操作,这里一共有四个操作可供选择:setbit、bitcount、bitpos、bitop,下面演示一下这些操作
# 设置字符串
set test a0
# 设置位,a0原来是 0110 0001 0011 0000,将第7位变成0,变成 0110 0000 0011 0000,于是变成了`0
setbit test 7 0
# 获取1的个数,因为test = 0110 0000 0011 0000 返回结果是4,表示有4个1
bitcount test
# 查找字符串中第一个设置为1或0的bit位。返回1
bitpos test 1 0 -1
# 将两个二进制串进行与或非操作
# test1 0110 0001
# test2 0110 0010
# test1 & test2 0110 0000
set test1 a
set test2 b
bitop and dest test1 test2
bitmap 有什么用呢?
用处:统计用户登录天数,且窗口随机
# 我在第1天登录了
setbit hellozjf 1 1
# 我在第7天登录了
setbit hellozjf 7 1
# 我在第364天登录了
setbit hellozjf 364 1
# 查询我整年登录了多少天,返回值是3,说明我今年登录了3天
bitcount hellozjf
# 查询我最近一周登录了多少天
bitcount hellozjf -7 -1,返回值是1,说明我最近一周登录了1天
List
redis 里面的 List 是一个双向队列,可以从头部插入数据、弹出数据,也可以从尾部插入、弹出数据
它拥有的操作为lpush
、lpop
、rpush
、rpop
、lrange
(查询列表中的元素)、lindex
(查询列表中的元素)、lset
(更新某个索引的值)、lrem
(删除元素)
# 插入队列,k1变成 f e d c b a
lpush k1 a b c d e f
# 查询列表
lrange k1 0 -1
# 查询第2个元素,查出 d
lindex k1 2
# 查询最后一个元素,查出 a
lindex k1 -1
# 设置第三个元素
lset k1 3 xxxxx
hash
value里面可以存储一个map,但是它只有一层。hash和sort set是两个非常常用的类型,需要重点掌握
通过在redis-cli
上面运行命令,运行help @hash,可以看到它拥有的操作为hdel
、hexists
、hget
、hgetall
、hincrby
、hincrbyfloat
、hkeys
、hlen
、hmget
、hmset
、hsetnx
、hstrlen
# 设置 k1.a=1
hset k1 a 1
# 获取 k1.a
hget k1 a
# 给 k1.a 增加1,之后k1.a变成2
hincrby k1 a 1
# 给 k1.a 增加0.5,之后k1.a变成2.5
hincrbyfloat k1 a 0.5
# 如果没有k1.b,则设置10,否则不设置
hsetnx k1 b 10
# 获取所有的k1下面所有的key和value
hgetall k1
# 判断某个键是否存在
hexists k1 a
……
其实也挺简单的,说白了就是 key-value 里面的 value 变成了 key-value
set
set其实和list差不多,只不过set里面没有重复的元素,但是它有个缺点就是元素是无序的
在redis-cli上面,运行help @set,可以看到所有的set相关的操作。例如sadd
(将元素加入到set里面)、SREM
(将元素从set中移除)、smembers
(获取所有的元素)、sdiff/sdiffstore
(两个set做相减操作/相减结果记录到另一个变量)、sinter/sinterstore
(求两个set的交集/相交结果记录到另一个变量)、sunion/sunionstore
(两个set做并集/并集结果记录到另一个变量)、srandmember
(从元素中获取随机的几个元素)、spop
(从元素中获取随机的几个元素,然后从set中删除它们)
sadd k1 a b c
sadd k2 b c d
# 获取 k1 - k2,结果存储到 k3,k3变成a
sdiffstore k3 k1 k2
# 获取 k1 与 k2 的交集,结果存储到 k4,k4变成b,c
sinterstore k4 k1 k2
# 获取 k1 与 k2 的并集,结果存储到 k5,k5变成a,b,c,d
sunionstore k5 k1 k2
# 买彩票,你把几个数字放进去,然后随机调出几个数字。比方说下面就是从10个数字里面随机调出3个数字
sadd k6 1 2 3 4 5 6 7 8 9 0
srandmember k6 3
# 年会抽奖,你把人的名字放进去,这个人中奖之后需要移除他的名字。
sadd k7 1 2 3 4 5 6 7 8 9 0
## 抽出4个四等奖
spop k7 4
## 抽出3个三等奖
spop k7 3
## 抽出2个二等奖
spop k7 2
## 抽出1个一等奖
spop k7 1
## 再抽返回null
sorted_set
再set的基础上面,增加了排序的功能。默认情况下,它在内存中是按照权重左小右大的方式进行存储的,通过ZRANGE
和ZREVRANGE
正序获取倒序获取结果,它也有差集、并集、交集的功能,但是个人感觉没啥意义,sorted_set在底层是通过跳表实现的
在redis-cli中,通过help @sorted_set
获取所有排序set的操作方法
# 往 sorted_set 中添加元素,其中张三权重1,李四权重2
zadd k1 1 张三 2 李四
# 查看 sorted_set 中的所有记录,这里如果中文编码不正确的话,使用 redis-cli --raw,这样redis就会将utf8字符串翻译成中文
zrange k1 0 -1 withscores
# 反向查看 sorted_set 中的所有记录
zrevrange k1 0 -1 withscores