关于后端:redis基本数据结构使用与场景

26次阅读

共计 4103 个字符,预计需要花费 11 分钟才能阅读完成。

[toc]

string(字符串)

用法

# 给 key 设置 value
set [key] [value]

# 依据 key 获取 value
get [key] 

# 依据 key 删除
del [key]

# 判断是否存在指定 key
exists [key]

# 批量存取键值对
mset [key1] [value1] [key2] [value2]

# 依据 key 批量获取 value
mget [key1] [key2]

# 给 key 设置对应的过期工夫 单位:秒
expire [key] [time]

# 等价于 set + expire 命令组合
setex    [key]  [time]  [value] 

# 如果 key 不存在则 set 创立,否则返回 0
setnx  [key]  [value]   

# 如果 value 为整数 可用 incr 命令每次自增 1
incr   [key]           
# 应用 incrby 命令对整数值 进行减少 number
incrby  [key] [number]  

应用场景

存储 key-value 键值对,能够用做缓存
应用 setnx 实现分布式锁
应用 incr 命令 用作计数器
分布式系统全局序列号

list(列表)

用法

# 将一个或多个值 插入到 key 列表的表头(最右边)lpush [key] [value1] [value2] 

# 将一个或多个值 value 插入到 key 列表的表尾(最左边)
rpush [key] [value1] [value2]

# 移除并返回 key 列表的头元素
lpop [key]

# 移除并返回 key 列表的尾元素
rpop [key]

# 返回列表 key 中指定区间内的元素,区间以偏移量 start 和 stop 指定
lrange [key] start stop

# 从 key 列表表尾弹出一个元素,若列表中没有元素,阻塞期待 timeout:秒,如果 timeout=0, 始终阻塞期待
brpop [key] timeout

# 从 key 列表表头弹出一个元素,若列表中没有元素,阻塞期待 timeout:秒,如果 timeout=0, 始终阻塞期待
blpop [key] timeout 

应用场景

  1. 模仿分布式系统数据结构
    Stack(栈) = LPUSH(右边放)+ LPOP(右边取)
    Queue(队列)= LPUSH(右边放)+ RPOP(左边取)
    Blocking MQ(阻塞队列)= LPUSH(右边放)+ BRPOP(左边阻塞取:没有数据就阻塞!)
  2. 公众号拉取文章,微博粉丝拉取被关注人的音讯
    发送者应用 lpush 将音讯搁置指定 key 中,接受者应用 lrang key 0 5 获取最新的五条音讯

set(不可反复,乱序的汇合)

用法

# 在 key 中插入多个元素
sadd [key] [value1] [value2]

# 指定 key 删除对应 value
srem [key] [value1] [value2]

# 查看指定 key 的汇合
smembers [key]

# 查看指定 key 的个数
scard [key]

# 判断 member 元素是否存在于汇合 key 中
sismember  [key]  [value1]

# 从汇合 key 中选出 count 个元素,元素不从 key 中删除
srandmember  [key]  [count]

# 从汇合 key 中选出 count 个元素,元素从 key 中删除
spop  [key]  [count]

# 交加运算
sinter  key  [key ...]

# 将交加后果存入新汇合 destination 中
sinterstore  destination  [key]  [key ..]

# 并集运算
sunion  key  [key ..]         

# 将并集后果存入新汇合 destination 中
SUNIONSTORE  destination  key  [key ...] 

# 差集运算
SDIFF  key  [key ...] 

# 将差集后果存入新汇合 destination 中
SDIFFSTORE  destination  key  [key ...]    

应用场景

  1. 随机抽奖

    1) 5 集体点击参加抽奖退出汇合
    SADD lottery 1001 1002 1003 1004 1005
    2) 查看参加抽奖的所有用户 ID
    SMEMBERS lottery
    3) 抽取 3 名获奖者
    SRANDMEMBER lottery 3  // 可反复获奖,用户 ID 不会从汇合中删除,能够参加下次抽奖
    SPOP lottery 3         // 不可反复获奖,用户 ID 从汇合中删除,无奈参加下次抽奖
  2. 社交软件 点赞 珍藏性能

    1) 用户 1001 给你这条音讯点了个赞
    SADD  thumbsUp:{音讯 ID}  1001
    2) 用户 1001 勾销点赞
    SREM  thumbsUp:{音讯 ID}  1001
    3) 检查用户 1001 是否点过赞
    SISMEMBER  thumbsUp:{音讯 ID}  1001
    4) 获取点赞的用户列表
    SMEMBERS thumbsUp:{音讯 ID}
    5) 获取点赞用户数 
    SCARD thumbsUp:{音讯 ID}

zset(绝对于 set 汇合 减少了 score 属性,score 可用于排序)

用法

# 增
zadd key 2 "two" 3 "three" -- 增加两个分数别离是 2 和 3 的两个成员
# 删
zrem key one two  -- 删除多个成员变量, 返回删除的数量
# 改

zincrby key 2 one -- 将成员 one 的分数减少 2,并返回该成员更新后的分数(分数扭转后相应它的 index 也会扭转)# 查 

# 返回所有成员和分数, 不加 WITHSCORES, 只返回成员 加 WITHSCORES 多返回分数
zrange key 0 -1 WITHSCORES 

# 依照元素的分值从小到大的程序返回从 start(0 开始)到 stop 之间的所有元素
zrange key start stop 

# 倒序获取有序汇合 key 从 start 下标到 stop 下标的元素 
zrevrange key start stop [WITHSCORES]    

# 获取成员 three 的分数
zscore key three 

# 获取分数满足表达式 1 < score <= 2 的成员
zrangebyscore key 1 2 

# 获取 key 键中成员的数量
zcard key       

# 获取分数满足表达式 1 <= score <= 2 的成员的数量
zcount key 1 2  

# 获取元素的排名,从小到大
zrank key member 

# 获取元素的排名,从大到小
zrevrank key member 

应用场景

  1. 排行榜

    zadd hotNews:20190819  1  '守护香港'
    1)点击一次”守护香港“这个新闻,那么此新闻的 score 属性 +1
      incrby hotNews:20190819 1 '守护香港'
    2)展现以后热搜新闻的前 10 名(最初的 WITHSCORES 代表查问出的后果蕴含具体的分数)ZREVRANGE  hotNews:20190819  0  10  WITHSCORES
    

hash(哈希表)

用法

-- 增
hset key field1 "s"   -- 若字段 field1 不存在, 创立该键及与其关联的 Hash, Hash 中,key 为 field1 , 并设 value 为 s,若字段 field1 存在, 则笼罩 
hmset key field1 "hello" field2 "world" -- 一次性设置多个字段    

-- 删
hdel key field1 -- 删除 key 键中字段名为 field1 的字段
del key  -- 删除键    

-- 改 
hincrby key field 1 -- 给 field 的值加 1

-- 查
hget key field1 -- 获取键值为 key, 字段为 field1 的值
hlen key        -- 获取 key 键的字段数量
hmget key field1 field2 field3 -- 一次性获取多个字段
hgetall key -- 返回 key 键的所有 field 值及 value 值
hkeys key   -- 获取 key 键中所有字段的 field 值
hvals key   -- 获取 key 键中所有字段的 value 值

应用场景

  1. 购物车

    hset cart:1001 10088 1      // 给用户 1001 增加商品 10088,数量为 1
    hincrby cart:1001 10088 1   // 用户 1001 将商品 10088 购买数量 +1
    hlen cart:1001              // 取得用户 1001 购物车商品总数
    hdel cart:1001 10088        // 用户 1001 将 10088 商品从购物车删除
    hgetall cart:1001           // 取得用户 1001 购物车的所有商品以及购买数量

redis 统计模式

redis 命令

聚合统计

利用 set 汇合 去重的个性,多个汇合之间取交加(sinter),并集(sunion),差集(sdiff)

排序统计

能够利用 list 插入时程序来排序(lpush + lrange),或者利用 sorted-set 的权重来排序(zadd + zrangebyscore)

二值状态统计

二值状态统计。这里的二值状态就是指汇合元素的取值就只有 0 和 1 两种。在签到打卡的场景中,咱们只用记录签到(1)或未签到(0),所以它就是十分典型的二值状态;

Bitmap 自身是用 String 类型作为底层数据结构实现的一种统计二值状态的数据类型。String 类型是会保留为二进制的字节数组,所以,Redis 就把字节数组的每个 bit 位利用起来,用来示意一个元素的二值状态。你能够把 Bitmap 看作是一个 bit 数组。

Bitmap 反对用 BITOP 命令对多个 Bitmap 按位做“与”“或”“异或”的操作

那么,具体该怎么用 Bitmap 进行签到统计呢?我还是借助一个具体的例子来阐明。

假如咱们要统计 ID 3000 的用户在 2020 年 8 月份的签到状况,就能够依照上面的步骤进行操作。

第一步,执行上面的命令,记录该用户 8 月 3 号已签到。

SETBIT uid:sign:3000:202008 2 1 

第二步,查看该用户 8 月 3 日是否签到。

GETBIT uid:sign:3000:202008 2 

第三步,统计该用户在 8 月份的签到次数。

BITCOUNT uid:sign:3000:202008

这样,咱们就晓得该用户在 8 月份的签到状况了

统计一亿个用户十天内又没有间断签到

基数统计

基数统计就是指统计一个汇合中不反复的元素个数

在统计 uv(页面访客个数)的场景,应用 set 汇合,hash 都能达到目标,毛病就是内存耗费高。

应用 HyperLogLog 能够极大升高内存的应用,毛病就是准确率会降落, 规范误算率是 0.81%

HyperLogLog 是一种用于统计基数的数据汇合类型,它的最大劣势就在于,当汇合元素数量十分多时,它计算基数所需的空间总是固定的,而且还很小。

援用

有一亿个 keys 要统计,应该用哪种汇合?

本文由 mdnice 多平台公布

正文完
 0