【面试题】redis五大数据类型、Bitmap

前言

redis命令不区分大小写,但是key是区分大小写的。

目前redis支持8种数据类型,最经典的还是前五种。

  • string:最基本的数据类型,二进制安全的字符串,最大512M。
  • list:按照添加顺序保持顺序的字符串列表。
  • hash:key-value对的一种集合。
  • set:无序的字符串集合,不存在重复的元素。
  • sorted set:已排序的字符串集合。
  • bitmap:更细化的一种操作,以bit为单位。
  • hyperloglog:基于概率的数据结构。
  • Geo:地理位置信息储存起来,并对这些信息进行操作

1. String

1.1 常用命令

set key value单个赋值
get key获取
del hello删除key
exists keykey是否存在 存在返回1不存在返回0
setnx key value分布式锁(不存在赋值成功)
ttl key查看过期时间
keys *查看所有key
mset key1 value1 key2 value2 …批量赋值
mget key1 key2…批量获取
incr key / incrby key N自增1/自增N
decr key / decrby key N自减1/自减N
strlen key字符串的长度
getrange key 0 4截取指定下标
setrange key 6 要替换的字符串从指定位置开始替换

1.2 应用场景

1.2.1 验证码

1.2.2 商品库存

2. hash

2.1 常用命令

hset key key1 value1
hmset set key key1 value1 key2 value2 …批量赋值
hget key key1
hmget get key key1 key2 …
hgetall key获取所有字段值
hlen key-获取某个key内全部数量
hdel key删除某个key

2.2 应用场景

2.2.1 对象

2.2.2 购物车的实现

用户312 增加商品pid001 数量1
hset shopcar:userid:312 pid001 1
用户312 增加商品pid002 数量1
hset shopcar:userid:312 pid002 1

商品数量002增加1
hincrby shopcar:userid:312 pid002 1

商品总数
hlen shopcar:userid:312

商品全选
hgetall shopcar:userid:312

3. list(数据可重复)

3.1 常用命令

Lpush list one从左插入一个值
Rpush list four从右插入一个值
Lpush list two three从左插入多个值
Rpush list two three从右插入多个值
Linsert list before two threetwo 之前插入 three
Linsert list after two threetwo 之后插入 three
Lpop list移除最左边的元素
Rpop list移除最右边的元素
Lrem list 1 k移除一个指定元素k
Lrem list 2 k移除两个指定元素k
Lset list 0 one赋值列表指定下标元素(如果列表不存在或者列表指定下标不存在,赋值失败。)
Llen list列表长度
Lrange list 0 1查询指定下标范围元素
Lrange list 0 -1-1 即表示查询所有元素
Lindex list 0下标从 0 开始
Ltrim list 1 2截取下标 1 到 2 的元素
Rpoplpush list list2移除列表最后一个元素并移动到新列表中

3.2 应用场景

list 实际是一个链表,左右都可以插入值。可以实现队列(先进先出),栈(先进后出)

3.2.1 微信订阅公众号推送文章

推送文章
lpush like:userid312 11
lpush like:userid312 22

获取文章列表
lrange like:userid312 0 -1 

3.2.2 取最新N个数据的操作(记录前N个最新登陆的用户Id列表)

//记录前N个最新登陆的用户Id列表,超出的范围可以从数据库中获得。
//把当前登录人添加到链表里
ret = r.lpush("login:last_login_times", uid)
//保持链表只有N位
ret = redis.ltrim("login:last_login_times", 0, N-1)
//获得前N个最新登陆的用户Id列表
last_login_list = r.lrange("login:last_login_times", 0, N-1)

4. set(数据不可重复)

4.1 常用命令

Sadd set hello插入元素
Smembers set取出所有元素
Sismember set hello存在返回 1,不存在返回0
Scard set元素个数
Srandmember set随机元素
Spop set随机弹出元素
Sdiff set1 set2取 set1 对于 set2 的差集
Sinter set1 set2取 set1 和 set2 的交集
Sunion set1 set2取 set1 和 set2 的并集
Srem set world删除指定元素
Smove set1 set2 hello移动 set1 中的 hello 到 set2 中(set2不存在则创建)

4.2 应用场景

4.2.1 微信小程序抽奖

在这里插入图片描述

4.2.2 朋友圈点赞

在这里插入图片描述

4.2.3 共同关注好友

在这里插入图片描述

4.2.4 可能认识的人

在这里插入图片描述

5. zset

5.1 常用命令

zadd key score1 member1 score2 member2 …添加一个元素以及该元素分数
zrem key member1移除元素
Zcard zset元素个数
zincrby key N member1增加某个元素的分数
zscore key member1获取元素的分数
zrangescore key min max获取指定分数范围内的元素
zcount key min max获取指定分数范围内的元素数量
Zrange zset 0 1正序查询指定下标范围
Zrangebyscore zset -inf +inf负无穷到正无穷正序排列
Zrem zset three移除指定元素

5.2 应用场景

5.2.1 销售排行榜

在这里插入图片描述

5.2.2 热搜

在这里插入图片描述

6.0 Bitmap

6.1 常用命令

setbit key offset value设置 key 的第 offset 位为 value (1 或 0)
getbit key offset获取 offset 设置的值,未设置过默认返回 0。
bitcount key [start, end]统计 key 上位为 1 的个数

6.2 应用场景

6.2.1 记录考勤

使用 bitmap 来记录一周的打卡记录(1 为打卡,0 为没打卡)

127.0.0.1:6379> setbit sign 0 1
(integer) 0
127.0.0.1:6379> setbit sign 1 0
(integer) 0
127.0.0.1:6379> setbit sign 2 0
(integer) 0
127.0.0.1:6379> setbit sign 3 1
(integer) 0
127.0.0.1:6379> setbit sign 4 1
(integer) 0
127.0.0.1:6379> setbit sign 5 0
(integer) 0
127.0.0.1:6379> setbit sign 6 0
(integer) 0

//统计这周打卡的记录
127.0.0.1:6379> bitcount sign
(integer) 3

7.0 案例分析

7.1 显示最新的项目列表

下面这个语句常用来显示最新项目,随着数据多了,查询毫无疑问会越来越慢。
SELECT * FROM foo WHERE … ORDER BY time DESC LIMIT 10
类似的问题就可以用Redis来解决。比如说,我们的一个Web应用想要列出用户贴出的最新20条评论。在最新的评论边上我们有一个“显示全部”的链接,点击后就可以获得更多的评论。

1.每次新评论发表时,我们会将它的ID添加到一个Redis列表:
LPUSH latest.comments <ID> 
2.我们将列表裁剪为指定长度,因此Redis只需要保存最新的5000条评论:
LTRIM latest.comments 0 5000 
3.每次我们需要获取最新评论的项目范围时,我们调用一个函数来完成(使用伪代码):
FUNCTION get_latest_comments(start, num_items):  
    id_list = redis.lrange("latest.comments",start,start+num_items - 1)  
    IF id_list.length < num_items  
        id_list = SQL_DB("SELECT ... ORDER BY time LIMIT ...")  
    END  
    RETURN id_list  
END 

这里我们做的很简单。在Redis中我们的最新ID使用了常驻缓存,这是一直更新的。但是我们做了限制不能超过5000个ID,因此我们的获取ID函数会一直询问Redis。只有在start/count参数超出了这个范围的时候,才需要去访问数据库。我们的系统不会像传统方式那样“刷新”缓存,Redis实例中的信息永远是一致的。SQL数据库(或是硬盘上的其他类型数据库)只是在用户需要获取“很远”的数据时才会被触发,而主页或第一个评论页是不会麻烦到硬盘上的数据库了。

7.2 删除与过滤

我们可以使用LREM来删除评论。如果删除操作非常少,另一个选择是直接跳过评论条目的入口,报告说该评论已经不存在。
redis 127.0.0.1:6379> LREM KEY_NAME COUNT VALUE

有些时候你想要给不同的列表附加上不同的过滤器。如果过滤器的数量受到限制,你可以简单的为每个不同的过滤器使用不同的Redis列表。毕竟每个列表只有5000条项目,但Redis却能够使用非常少的内存来处理几百万条项目。

7.3 排行榜

另一个很普遍的需求是各种数据库的数据并非存储在内存中,因此在按得分排序以及实时更新这些几乎每秒钟都需要更新的功能上数据库的性能不够理想。
典型的比如那些在线游戏的排行榜,比如一个Facebook的游戏,根据得分你通常想要:

  • 列出前100名高分选手
  • 列出某用户当前的全球排名
    这些操作对于Redis来说小菜一碟,即使你有几百万个用户,每分钟都会有几百万个新的得分。
    模式是这样的,每次获得新得分时,我们用这样的代码:
    ZADD leaderboard
    你可能用userID来取代username,这取决于你是怎么设计的。
    得到前100名高分用户很简单:ZREVRANGE leaderboard 0 99。
    用户的全球排名也相似,只需要:ZRANK leaderboard 。

视频链接:https://www.bilibili.com/video/BV1S54y1R7SB?p=21&spm_id_from=pageDriver&vd_source=b901ef0e9ed712b24882863596eab0ca

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值