首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >公开课 redis系列二----五大类型的使用场景

公开课 redis系列二----五大类型的使用场景

作者头像
用户7798898
发布2022-05-09 16:33:38
2930
发布2022-05-09 16:33:38
举报

redis的五大类型是

string, list, hash, set, zset


科普: redis cli的用法

1. redis-cli 打开redis客户端, 这就不用说了

2. help, 查看redis-cli的命令

 这里告诉你redis 命令的类型.

help @<group> 获取一组命令行. 比如获取string类型的一组命令行

重点: 可以试用help @+tab键来切换group的类型

例如: help @+tab

第一个出现的是help @generator, 第二个出现的是help @string

help @string

回车, 看看string命令组有哪些命令

为什么说这个? 虽然redis经常用, 但是, 有些功能是盲区, 但是可以让我们很快进入状态. 比如你忘了那个命令怎么写了,那么就使用help, 不用去费劲百度了.


一. string

1. 存储string 和int类型

这个我们都比较熟悉. 来看看string的内部方法.

string可以保存三种类型的数据: string  int  bitmap(二进制) 

使用redis-cli 的help @string. 

我们set 一个字符串和一个int

set c1 abcdef
get c1

set c2 9
get c2

接下来我们看看字符串的长度

 我们来看看c1和c2的编码类型, 使用Object命令, 我们不知道Object的用法. 那么就help一下

object help

 里面有一个encoding, 这个就是获取指定key的类型

// 获取c1的类型
OBJECT encoding c1

// 获取c2的类型
OBJECT encoding c2

我们看看返回的结果

第一个字符串返回的是embstr, 第二个返回的是int 

这里embstr表示的是字符串类型, int是数值类型. 还有一个字符串类型是raw. redis5.X的版本, 字符串长度小于44, 返回embstr类型, 字符串长度>44, 返回raw类型

raw就是 返回原始数据, 未经加工的数据

raw的用法

有时, 我们在set一个汉字的时候, 会发现, get出来的是一个编码, 而不是汉字本身. 例如: 

127.0.0.1:6379> set a1 罗
OK

127.0.0.1:6379> get a1
"\xe7\xbd\x97"

如果要想打印出汉字本身, 我们可以使用raw参数, 表示按照原始的未加工的方式输出

// 第一步: 启动客户端的时候, 增加--raw参数
redis-cli --raw

// 第二步: get出数据, 这是返回的是原始数据
get a1

int类型还可以使用自增, 自减的本地方法

// 每次自增1
127.0.0.1:6379> get c2
9
127.0.0.1:6379> INCR c2
10

// 每次自增指定步长
127.0.0.1:6379> get c2
10
127.0.0.1:6379> INCRBY c2 100
110
127.0.0.1:6379> get c2
110

使用场景: 秒杀, 限流, 值变化

2. bitmap二进制类型 

以前很少接触到二进制类型, 这次突然知道, 为什么大神们都喜欢用二进制表示.

在help @string中可以看到很多bit开头的命令, 这些就是操作二进制的

下面说两个问题

1. 二进制怎么用, 这个是通用的, java, c都是可以这么使用

2. 二进制在什么场景用

使用二进制速度快, 对内存非常友好, 对cpu也非常友好

1) 二进制怎么用

  • 设置1个字节

SETBIT: 这个命令是开辟一个空间, 给某个偏移量设置某个值

127.0.0.1:6379> SETBIT c1 1 1
0

参数的含义

参数的含义 
c1 -->是key
1 -->表示偏移量
1 -->表示设置偏移量的值

这句话什么意思呢?

首先. SETBIT命令会开辟一块空间. 这块空间是一个地址, 按字节来计算
1个字节 = 8byte
开辟完是这样的
00000000


第二: 对这个字节的下标为1的字节, 将其值修改1
修改后: 010000000

接下来, 我们get一下,看看c1是什么东西

127.0.0.1:6379> get c1
@

c1是一个@符号. 这表示 01000000这ascii中表示的是@

我们再来setbit c1 7 1 

这是就变成: 01000001了, 这是个什么呢?

127.0.0.1:6379> get c1
A

表示01000001这个在ascii中表示的是A

这是他的用法. 我们再来看看c1的长度

127.0.0.1:6379> STRLEN c1
1

这里c1 的长度是1, 这里的1表示的一个字节, 我给c1的偏移量始终都没有超过1个字节

  • 设置多个字节

 刚才我们设置了一个1字节的c1, 那么看看下面这个是什么呢?

// 给c1 再设置第九个偏移量为1
127.0.0.1:6379> SETBIT c1 9 1
0

// 取出c1 结果为A@
127.0.0.1:6379> get c1
A@

为什么会这样?

SETBIT c1 9 1 给9个偏移量设置1, 1byte只有8位, 给下标为9的位set, 那就要再开辟一个字节. 变成这样
01000001 01000000

我们来看现在是几个字节

127.0.0.1:6379> STRLEN c1
2

果然, 现在是两个字节.

也就是说: setbit可以的动态拓宽字节

  • BITCOUNT的用法
// BITCOUNT统计指定key的字节中1的个数

127.0.0.1:6379> BITCOUNT c1 0 1
3

BITCOUNT什么意思? BITCOUNT统计指定key的字节中1的个数

参数是什么意思呢?

// 参数含义:
c1 表示的是要统计的key
0 代表从第0个字节开始统计, 不是位数, 是字节数
1 代表从到第1个字节结束, 不是位数, 是字节数

所以, c1 统计的结果是0和1两个字节中包含1的个数, 答案是3个

比如说, 我还可以统计, 0号字节---0号字节有多少个1, 1号字节---1号字节有多少个1

127.0.0.1:6379> BITCOUNT c1 0 0
2
127.0.0.1:6379> BITCOUNT c2 1 1
1

0号字节---0号字节有多少个1, 有2个1

1号字节---1号字节有多少个1, 有1个1

  • 案例: 再来看 如果一年有365天, 我要标记哪天早起了. 我应该怎么做呢?

首先, 我们先来开辟一个365位的空间

127.0.0.1:6379> SETBIT c3 365 0

我们看看这个空间占了多少字节?

127.0.0.1:6379> STRLEN c3
46

占了46个字节. 哇🤩,我要统计365天的早起情况, 这里一共才用了46个字节, 连1k都不到. 和数据库存储对比, 是不是很节省空间?

接下来统计早起的天数,使用BITCOUNT

127.0.0.1:6379> BITCOUNT c3 0 -1
0

早起天数是0天,还没有早起过. 

接下来设置我第3天早起了

127.0.0.1:6379> SETBIT c3 2 1
0

再来统计我早起的天数

127.0.0.1:6379> BITCOUNT c3 0 -1
1

答案是1天. 

这样真的很不错, 可以很简单的统计出我早起的天数. 

我还想看看我第5天早起了么, 第3天早起了么?

127.0.0.1:6379> GETBIT c3 4
0

127.0.0.1:6379> GETBIT c3 2
1

可以清晰的看出, 第五天没有早起, 第三天早起了. 

  • BITOP : 按位操作的与或非

我们先准备数据

127.0.0.1:6379> SETBIT c1 1 1
0
127.0.0.1:6379> SETBIT c1 7 1
0
127.0.0.1:6379> GET c1
A



127.0.0.1:6379> SETBIT c2 1 1
0
127.0.0.1:6379> SETBIT c2 6 1
0
127.0.0.1:6379> get c2
B

现在准备好了两个数据c1和c2 , c1是01000001 大写字母A, c2是01000010, 大写字母B

记下来我们对c1, c2进行操作

    • 先进行and操作
    • 再进行or操作
    127.0.0.1:6379> BITOP or orkey c1 c2
    1
    127.0.0.1:6379> get orkey
    C
127.0.0.1:6379> BITOP and andkey c1 c2
1
127.0.0.1:6379> get andkey
@

为什么是@和C呢?

 使用场景

1. 统计  一个用户  任意时间段内  登录天数

什么意思? 比如双十一 要统计所有用户的用户登录天数

要是用数据库怎么做? 用户登录一次, 记一条记录, 又登录一次, 又记录一条. 然后汇总.

要是用我们知道二进制, 那么用二进制要简单的多

比如: 用户a 第二天登录了一次

127.0.0.1:6379> SETBIT a 1 1
0

用户a第365天登录了一次

127.0.0.1:6379> SETBIT a 364 1
0
127.0.0.1:6379> STRLEN a
46

365天的登录情况, 我们来看看占用了多少个字节, 46个字节, 连1k都不到. 非常节省空间

这个用户一年登录了几次呢?

127.0.0.1:6379> BITCOUNT a 0 -1
2

0表示从头开始统计, -1表示从后往前算,依次是-1, -2 -3

用户365天里一共登录了2次

2. 统计 一段时间内, 活跃用户的数量

也就是比如1年内, 有多少用户登录过

举个例子:

id号为1的用户20200101登录了

127.0.0.1:6379> SETBIT 20200101 1 1
0
20200101表示的是登录日期
1 表示的用户的id号
1 表示登录的标记

id号为2的用户20200101也登录了

127.0.0.1:6379> SETBIT 20200101 2 1
0

id号为1的用户20200102登录了

127.0.0.1:6379> SETBIT 20200102 1 1
0

统计2天内, 访问的用户数

11000000

10000000

------------

11000000

对两个数据取并集即可得到用户登录数了

// 统计两天内登录的人数, 取集合的并集, 也就是多次登录算一次
BITOP or userCount 20200101 20200102
1

BITCOUNT userCount 0 -1
2

得到的结果也是2. 一共有两个人登录过了.

我想知道所有用户, 在三天内登录的次数

只需要对a和b的用户数进行or操作

 二. List

redis中的list是一个双向链表

我们来看看list中有哪些命令

help @list

 L开头的表示从链表的左边开始操作, R开头的表示从链表的右边开始操作

这里有几个命令

  • LPUSH
127.0.0.1:6379> LPUSH k a b c d e
5

向key为k的链表中放5个元素, Lpush表示的是从左测push. 那么push的结果是? 可以使用LRange取出来全部的元素

  • LRANGE
127.0.0.1:6379> LRANGE k 0 -1
e
d
c
b
a

我们发现, 取出是从e d c b a的顺序. 

还可以使用RPush, 从右侧推入一个元素x

127.0.0.1:6379> RPUSH k x
6

取出返回结果是

127.0.0.1:6379> LRANGE k 0 -1
e
d
c
b
a
x

x从右侧被加入了. 

注: 这里LRange表示遍历, L字母是list的首字母L, 而不是Left的首字母L

  • LPOP : 从左侧弹出一个元素
127.0.0.1:6379> LPOP k 
e
  • RPOP: 从右侧弹出一个元素
127.0.0.1:6379> RPOP k
x
  • LINDEX

取出第几个元素, 比如取出第二个元素

127.0.0.1:6379> LRANGE k 0 -1
e
d
c
b
a
x

127.0.0.1:6379> LINDEX k 3
b
  • LTRIM: 删除元素

注意: LTrim删除元素的方式和通常是相反的. 他设置的start和end是保存下来的元素

比如:

127.0.0.1:6379> LRange k 0 -1
d
c
b
a

127.0.0.1:6379> LTRIM k 0 -1
OK

原来有d c b a 四个元素, 现在删除, 从头开始, 到最后一个

得到的结果是什么呢?

127.0.0.1:6379> LRange k 0 -1
d
c
b
a

依然还是四个元素. 

我们删除第一个元素, 怎么表示呢?

127.0.0.1:6379> LTRIM k 1 -1
OK

第一个参数表示要保留的起始下标的位置是1, 要保留的结束下标位置是-1

也就是删除了第一个元素

127.0.0.1:6379> LRange k 0 -1
c
b
a

List的使用场景

1. 栈   同向指令  左边压入, 右边弹出 
2. 队列, 异向指令, 左边压入, 右边弹出. 
3. 数组. 

 三. Hash

help @hash

老师将的是hash的基本用法

  • HSET
127.0.0.1:6379> hset lily name lxl
1
127.0.0.1:6379> hset lily age 18
1
127.0.0.1:6379> hset lily sex 1
1
  • HGET
127.0.0.1:6379> HGET lily name
lxl
  • HGETALL
127.0.0.1:6379> HGETALL lily
name
lxl
age
18
sex
1
  • HKEYS
127.0.0.1:6379> HKEYS lily
name
age
sex
  • HVALS
127.0.0.1:6379> HVALS lily
lxl
18
1

hset的使用场景

1. 详情页内容.
2. 需要聚合的内容, 把聚合结果保存到hash里

四. SET

help @SET

  •  SADD
127.0.0.1:6379> SADD k1 aba bab baa bbb aba
4

加入5个字符串, 有两个是重复的,排重后只有4个

  • SMEMBERS 取出所有的成员
127.0.0.1:6379> SMEMBERS k1
bbb
bab
baa
aba
  • SRANDMEMBER

  随机取出成员. 语法是:  SRANDMEMBER  key  num

      他有四种情况. 比如上面的demo, set集合里有4个元素. 

  num可以是3, 8 ,-3, -8

  num等于3 : 表示随机取出不重复的3个字符串

127.0.0.1:6379> SRANDMEMBER k1 3
bab
bbb
baa
127.0.0.1:6379> SRANDMEMBER k1 3
bab
aba
baa

  num等于8: 一共只有4个字符串, 最多返回4个

127.0.0.1:6379> SRANDMEMBER k1 8
bab
bbb
aba
baa

  num等于-3: 表示随机取出可以重复的3个字符串

127.0.0.1:6379> SRANDMEMBER k1 -3
baa
aba
aba
127.0.0.1:6379> SRANDMEMBER k1 -3
aba
baa
aba

  num等于-8: 表示根据num的个数随机取, 满足个数要求

127.0.0.1:6379> SRANDMEMBER k1 -8
bbb
bbb
aba
bab
aba
bab
baa
baa
127.0.0.1:6379> SRANDMEMBER k1 -8
baa
aba
baa
aba
baa
aba
aba
aba

取随机数的使用场景: 

比如: 随机抽奖
某一个人不可以重复中奖, 使用srangmember 中num为正数
某个人可以重复中奖, 使用srangmember 中num为负数

p.p1 { margin: 0; font: 11px Menlo; color: rgba(0, 0, 0, 1) } span.s1 { font-variant-ligatures: no-common-ligatures }

  • SUNION : 取并集
127.0.0.1:6379> sadd k1 a b c
3
127.0.0.1:6379> sadd k2 a x y
3
127.0.0.1:6379> SUNION k1 k2
y
a
b
c
x

p.p1 { margin: 0; font: 11px Menlo; color: rgba(0, 0, 0, 1) } span.s1 { font-variant-ligatures: no-common-ligatures }

  • SINTER: 取交集
127.0.0.1:6379> SINTER k1 k2
a

p.p1 { margin: 0; font: 11px Menlo; color: rgba(0, 0, 0, 1) } span.s1 { font-variant-ligatures: no-common-ligatures }

  • SDIFF: 取差集 差集是有方向的
127.0.0.1:6379> SDIFF k1 k2
c
b
127.0.0.1:6379> SDIFF k2 k1
x
y

取交并差集的使用场景

集合操作的使用场景:

推荐系统
用户A和用户B
A&B: AheB都认识的人
AorB: AheB认识的所有人
A和B的差集: A认识B不认识, 或者B认识A不认识的人

五. zset

zset的help帮助文档, 和其他四个不同, help @sorted_set

p.p1 { margin: 0; font: 11px Menlo; color: rgba(0, 0, 0, 1) } span.s1 { font-variant-ligatures: no-common-ligatures }

  • ZADD: 添加
127.0.0.1:6379> zadd rank 1 apple 2 banana 3 pear
3
  • ZRANGE : 按照正序取出所有元素和分数
127.0.0.1:6379> ZRANGE rank 0 -1 withscores
apple
1
banana
2
pear
3
  • ZREVRANGE: 按照逆序取出排行榜前两名的元素
127.0.0.1:6379> ZREVRANGE rank 0 1 withscores
pear
3
banana
2
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-03-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 科普: redis cli的用法
    • 重点: 可以试用help @+tab键来切换group的类型
    • 一. string
      • 1. 存储string 和int类型
        • 2. bitmap二进制类型 
          • 1) 二进制怎么用
        •  使用场景
          • hset的使用场景
      •  二. List
      •  三. Hash
      • 四. SET
        • 取随机数的使用场景: 
          • 取交并差集的使用场景
          • 五. zset
          相关产品与服务
          云数据库 Redis
          腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档