Redis基础知识(学习笔记1--五种基础数据结构)

Redis 有5种基础数据结构,分别为string(字符串)、list(列表)、hash(字典)、set(集合)和zset(有序集合)。

1 String 结构

1.1 字符串常用操作

SET key value                    //存入字符串键值对
MSET key value [key value...]    //批量存储字符串键值对
SETNX key value                  //存入一个不存在的字符串键值对,如果已将存在,则set创建不成功,原来的值不变。
GET key                          //获取一个字符串键值
MGET key [key...]                //批量获取字符串键值
DEL key [key...]                 //删除一个健
EXPIRE key seconds               //设置一个健的过期时间(秒)

1.2 原子操作

INCR key                       //将key所存储的数字值加1--value值需要是整数,它的范围在signed long 的最大值和最小值之间,超出范围,会报错。
DECR key                       //将key所存储的数字值减1
INCRBY key increment           //将key所存储的值加上increment
DECRby key decrement           //将key所存储的值减去decrement

 2. String 应用场景

2.1 单值缓存

SET key value
GET key

2.2 对象缓存

SET user:1 value(json格式数据)

2.3 分布式锁

SETNX product:10001 true            //返回1代表获取锁成功
SETNX product:10001 true           //返回0代表获取锁失败
...执行业务操作
DEL product:10001                  //执行完业务释放锁
SET product:10001 true ex 10 nx    //防止程序意外终止导致死锁

2.4 计数器

INCR article:readcount:{文章id}
GET  article:readcount:{文章id}

2.5 分布式系统全局序列号

INCRBY orderId 100   //redis批量生成序列号提升性能

3. Hash 结构

Redis的hash相当于Java里面的HashMap,它是无序字典,内部存储了很多键值对。

Hash 常用操作

HSET key field value                      // 存储一个哈希表key的键值
HSETNX key field value                    // 存储一个不存在的哈希表key的键值
HMSET key field value [field value...]   //在一个哈希表key中存储多个键值对
HGET key field                           //获取哈希表key对应的field键值
HMGET key field [field...]               //批量获取哈希表key中多个field键值
HDEL key field [field...]                //删除哈希表key中的field键值
HLEN key                                 //返回哈希表key中field的数量
HGETALL key                              //返回哈希表key中所有的键值

HINCRBY key field increment             //为哈希表key中field健的值加上增量increment

当hash移除了最后一个元素之后,该数据结构被自动删除,内存数据被回收。

4 Hash 应用场景

4.1 对象缓存

hash 结构可以用来存储用户信息,与字符串需要一次性全部序列化整个对象不同,hash可以对用户结构中的每个字段单独存储。这样当我们需要获取用户信息时,可以进行部分获取。

// 例如记录员工的信息(userid、username、balance)
HMSET user {userid}:name xiaoming {userid}:balance 30000
HMSET user 1:name xiaoming 1:balance 30000
HMGET user 1:name 1:balance

 4.2 电商购物车

1)以用户id为key;2)以商品id为field;3)以商品数量为value。

购物车操作(假设此时用户的id为1001;商品id为10088)

1)添加商品--> hset cart:1001 10088 1

2)增加数量-->hincrby cart:1001

3) 商品总数-->hlen cart:1001

4)删除商品-->hdel cart:1001 10088

5)获取购物车所有商品-->hgetall cart:1001

5.List 结构

List常用操作

LPUSH key value [value...]       //将一个或多个值value插入到key列表的表头(最左边)
RPUSH key value [value...]       //将一个或多个值value插入到key列表的表尾(最右边)
LPOP key                         //移除并返回key列表的头元素
RPOP key                         //移除并返回key列表的尾元素
LRANGE key start stop            //返回列表key中指定区间内的元素,区间以偏移量start和stop指定

BLPOP key [key...] timeout       //从key列表表头弹出一个元素,若列表中没有元素,阻塞等待timeout秒,如果timeout=0,一直阻塞等待

BRPOP key [key...] timeout       //从key列表表尾弹出一个元素,若列表中没有元素,阻塞等待timeout秒,如果timeout=0,一直阻塞等待

 List 是链表而不是数组。这意味着list的插入和删除操作非常快,时间复杂度为O(1),但是索引定位很慢,时间复杂度为O(n)。

当列表弹出了最后一个元素之后,该数据结构被自动删除,内存数据被回收。

6 List应用场景

列表结构常用来做异步队列使用。将需要延后处理的任务结构体序列化成字符串,塞进Redis列表,另一个线程从这个列表种轮询数据进行处理。

6.1 常用分布式数据结构

队列是 先进先出 的数据结构,常用于消息排队和异步逻辑处理,它会确保元素的访问顺序。

Queue(队列) = LPUSH + RPOP

栈是 先进后出 的数据结构,跟队列正好相反。

Stack(栈) = LPUSH + LPOP

Blocking MQ(阻塞队列) = LPUSH + BRPOP

6.2 微博和微信公众号消息流

 假如小明关注了Caoz,疯狂赛车等大V

1)Caoz发微博,消息ID为10018

LPUSH msg:{小明-id} 10018

2)疯狂赛车发微博,消息ID为10086

LPUSH msg:{小明-id} 10086

3)显示最新的5条微博消息

LRANGE msg:{小明-id} 0 4

7 Set 结构

set 相当于Java里面的HashSet,它内部的键值对是无序的、唯一的。它的内部实现相当于一个特殊的字典,字典中所有的value都是一个值NULL。

当集合中最后一个元素被移除后,数据结构被自动删除,内存被回收。

7.1 Set 常用操作

SADD key member [member...]        //往集合key中存入元素,元素存在则忽略,若key不存在则新建
SREM key member [member...]        //从集合key中删除元素
SMEMBERS key                       //获取集合key中所有元素
SCARD key                          //获取集合key的元素个数
SISMEMBER key member               //判断member元素是否存在于集合key中
SRANDMEMBER key [count]            //从集合key中随机选出count个元素,元素不从key中删除
SPOP key [count]                   //从集合key中随机选出count个元素,元素从key中删除

7.2 Set运算操作

SINTER key [key...]                    //交集运算
SINTERSTORE destination key [key...]   //将交集结果存入新集合destination中
SUNION key [key...]                    //并集运算
SUNIONSTORE destination key [key...]   //将并集结果存入新集合destination中
SDIFF key [key...]                     //差集运算
SDIFFSTORE destination key [key...]   //将差集结果存入新集合destination中

 8. Set 应用场景

8.1 微信抽奖小程序

1)点击参加抽奖进入集合

SADD key {userID}   ----注意:此时key应替换为抽奖活动的ID

2)查看参与抽奖所有用户

SMEMBERS key

3)抽取count名中奖者

SRANDMEMBER key [count] /SPOP key [count] 

8.2 微信微博点赞,收藏,标签

1)点赞

SADD like:{消息ID} {用户ID}

2)取消点赞

SREM  like:{消息ID} {用户ID}

3)检查用户是否点过赞

SISMEMBER  like:{消息ID} {用户ID}

4)获取点赞的用户列表

SMEMBERS like:{消息ID}

5)获取点赞用户数

SCARD  like:{消息ID}

 8.3 通过集合操作 实现微博微信关注模型

1)诸葛老师关注的人:

zhugeSet-->{zhuangzhou,xushu}

2)楼兰老师关注的人:

loulanSet-->{zhuge,zhouyu,zhuangzhou,xushu}

3)庄周老师关注的人:

zhuangzhouSet-->{zhuge,loulan,zhouyu,xushu,xunyu}

4)诸葛老师和楼兰老师共同关注:

SINTER zhugeSet loulanSet -->{zhuanzhou,xushu}

5)我【诸葛老师】关注的人也关注他(楼兰老师):【解析:我关注的就两个人嘛 ,即zhuangzhou和xushu,那就去这两个人的集合中,去判断元素是否存在集合中呗】

SISMEMBER zhuangzhouSet loulan

SISMEMBER xushuSet loulan

6)我可能认识的人:

SDIFF loulanSet zhugeSet-->{zhuge,zhouyu}

9 ZSet 有序集合结构

zset 类似于Java中的SortedSet 和 HashMap的结合体,一方面它是一个set,保证了内部value的唯一性,另一方面,它可以给每个value赋予一个score,代表这个value的排序权重。

9.1 ZSet 常用操作

ZADD key score member [[score member]...]     //往有序集合key中加入带分值元素
ZREM key member [member...]                   //从有序集合key中删除元素
ZSCORE key member                             //返回有序集合key中元素member的分值
ZINCBY key increment member                   //为有序集合key中元素member的分值加上increment
ZCARD key                                     //返回有序集合key中元素个数
ZRANGE key start stop [WITHSCORES]            //正序获取有序集合key从start下标到stop下标的元素
ZREVRANGE key start stop [WITHSCORES]         //倒序获取有序集合key从start下标到stop下标的元素

9.2 ZSet集合操作

ZUNIONSTORE destkey numkeys key [key]  //并集计算
ZINTERSTORE destkey numkeys key [key]  //交集计算

zset中最后一个value被移除后,数据结构被自动删除,内存被回收。

 10 ZSet 集合操作实现排行榜

1)点击新闻

ZINCRBY hotNews:20200819 1 XX发布会

2)展示当日排行前十

ZREVRANGE hotNews:20200819 0 9 WITHSCORES

3)七日搜索榜单计算

ZUNIONSTORE hotNews:20200813-20200819 7 hotNews:20200813 hotNews:20200814...hotNews:20200819

4)展示七日排行前十

ZREVRANGE hotNews:20200813-20200819 0 9 WITHSCORES

 11  结构总结

 12 容器类型数据结构的通用规则

list、set、hash、zset 这四种数据结构都是容器类型数据结构,他们共享下面两条通用规则

1)create if not exists

如果容器不存在,就创建一个,再进行操作。

比如rpush操作刚开始是没有列表的,Redis就会自动创建一个,然后再rpush进去新元素。

2)drop if not elements

如果容器里的元素没有了,那么立即删除容器,释放内存。这意味着lpop操作到最后一个元素,列表就消失了。

 

学习参阅声明

1.--【从原理到实战(2023最新版)】

https://www.bilibili.com/video/BV1Gs4y1Q7Ls?p=6&vd_source=0e347fbc6c2b049143afaa5a15abfc1c

2.《Redis深度历险--核心原理与应用实践》

热门相关:逃妻鲜嫩嫩:霸道老公,吻够没   重生之神级败家子   末日终战   农家小地主   豪门宠婚:权少夫人萌上天