玩玩Redis系列(二)
2021/4/25 19:25:21
本文主要是介绍玩玩Redis系列(二),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
玩玩Redis系列二
- Redis数据结构&相关命令&使用场景
- 1 string(字符串)
- 1.1 数据结构
- 1.2 对字符串的基本操作
- 1.2.1 设置和获取键值对
- 1.2.2 使用 EXISTS 和 DEL 关键字来查询是否存在和删除键值对:
- 1.2.3 批量设置键值对
- 1.2.4 过期和 SET 命令扩展
- 1.2.5 计数
- 1.2.6 返回原值的 GETSET 命令
- 1.2.7 命令小结
- 1.3 使用场景
- 2 list(列表)
- 2.1 数据结构
- 2.2 常用命令
- 2.3 使用场景
- 3 hash(字典)
- 3.1 数据结构
- 3.2 常用命令
- 3.3 使用场景
- 4 set(集合)
- 4.1 数据结构
- 4.2 常用命令
- 4.3 使用场景
- 5 zset(有序集合)
- 5.1 数据结构
- 5.2 常用命令
- 5.3 使用场景
- 6 总结
Redis数据结构&相关命令&使用场景
Redis 有 5 种基础数据结构,它们分别是:string(字符串)、list(列表)、hash(字典)、set(集合) 和 zset(有序集合)。这 5 种是 Redis 相关知识中最基础、最重要的部分,下面我们结合源码以及一些实践来给大家分别讲解一下。
数据结构 | 底层实现 |
---|---|
string(字符串) | 字符数组(动态字符串) |
list(列表) | 链表 |
hash(字典) | 数组 + 链表 |
set(集合) | hash(字典)字典中所有的 value 都是一个值 NULL |
zset(有序集合) | 跳跃表 |
1 string(字符串)
1.1 数据结构
Redis 中的字符串是一种 动态字符串,这意味着使用者可以修改,它的底层实现有点类似于 Java 中的 ArrayList,有一个字符数组 Redis规定字符串大小不能超过512M
1.2 对字符串的基本操作
1.2.1 设置和获取键值对
> SET key value OK > GET key "value"
使用 SET 和 GET 来设置和获取字符串值。
值可以是任何种类的字符串(包括二进制数据),例如你可以在一个键下保存一张 .jpeg 图片,只需要注意不要超过 512 MB 的最大限度就好了。
当 key 存在时,SET 命令会覆盖掉你上一次设置的值:
> SET key newValue OK > GET key "newValue"
1.2.2 使用 EXISTS 和 DEL 关键字来查询是否存在和删除键值对:
> EXISTS key (integer) 1 > DEL key (integer) 1 > GET key (nil)
1.2.3 批量设置键值对
> SET key1 value1 OK > SET key2 value2 OK > MGET key1 key2 key3 # 返回一个列表 1) "value1" 2) "value2" 3) (nil) > MSET key1 value1 key2 value2 > MGET key1 key2 1) "value1" 2) "value2"
1.2.4 过期和 SET 命令扩展
可以对 key 设置过期时间,到时间会被自动删除,这个功能常用来控制缓存的失效时间。(过期可以是任意数据结构)
> SET key value1 > GET key "value1" > EXPIRE name 5 # 5s 后过期 ... # 等待 5s > GET key (nil)
等价于 SET + EXPIRE 的 SETEX 命令:
> SETEX key value1 ... # 等待 5s 后获取 > GET key (nil) > SETEX key value1 # 如果 key 不存在则 SET 成功 (integer) 1 > SETEX key value1 # 如果 key 存在则 SET 失败 (integer) 0 > GET key "value" # 没有改变
1.2.5 计数
如果 value 是一个整数,还可以对它使用 INCR 命令进行 原子性 的自增操作,这意味着及时多个客户端对同一个 key 进行操作,也决不会导致竞争的情况:
> SET counter 100 > INCR count (interger) 101 > INCRBY counter 50 (integer) 151
1.2.6 返回原值的 GETSET 命令
对字符串,还有一个 GETSET 比较让人觉得有意思,它的功能跟它名字一样:为 key 设置一个值并返回原值:
> SET key value > GETSET key value1 "value"
1.2.7 命令小结
set [key] [value] 给指定key设置值(set 可覆盖老的值) get [key] 获取指定key 的值 del [key] 删除指定key exists [key] 判断是否存在指定key mset [key1] [value1] [key2] [value2] ...... 批量存键值对 mget [key1] [key2] ...... 批量取key expire [key] [time] 给指定key 设置过期时间 单位秒 setex [key] [time] [value] 等价于 set + expire 命令组合 setnx [key] [value] 如果key不存在则set 创建,否则返回0 incr [key] 如果value为整数 可用 incr命令每次自增1 incrby [key] [number] 使用incrby命令对整数值 进行增加 number
1.3 使用场景
存储key-value键值对,这个比较简单不细说了,一般计数器,图片二进制,html二进制,js二进制等等
2 list(列表)
2.1 数据结构
Redis中的list和Java中的LinkedList很像,底层都是一种链表结构, list的插入和删除操作非常快,时间复杂度为 0(1),不像数组结构插入、删除操作需要移动数据。
像归像,但是redis中的list底层可不是一个双向链表那么简单。
当数据量较少的时候它的底层存储结构为一块连续内存,称之为ziplist(压缩列表),它将所有的元素紧挨着一起存储,分配的是一块连续的内存;当数据量较多的时候将会变成quicklist(快速链表)结构。
可单纯的链表也是有缺陷的,链表的前后指针 prev 和 next 会占用较多的内存,会比较浪费空间,而且会加重内存的碎片化。在redis 3.2之后就都改用ziplist+链表的混合结构,称之为 quicklist(快速链表)。
2.2 常用命令
rpush [key] [value1] [value2] ...... 链表右侧插入 rpop [key] 移除右侧列表头元素,并返回该元素 lpop [key] 移除左侧列表头元素,并返回该元素 llen [key] 返回该列表的元素个数 lrem [key] [count] [value] 删除列表中与value相等的元素,count是删除的个数。 count>0 表示从左侧开始查找,删除count个元素,count<0 表示从右侧开始查找,删除count个相同元素,count=0 表示删除全部相同的元素 (PS: index 代表元素下标,index 可以为负数, index= 表示倒数第一个元素,同理 index=-2 表示倒数第二 个元素。) lindex [key] [index] 获取list指定下标的元素 (需要遍历,时间复杂度为O(n)) lrange [key] [start_index] [end_index] 获取list 区间内的所有元素 (时间复杂度为 O(n)) ltrim [key] [start_index] [end_index] 保留区间内的元素,其他元素删除(时间复杂度为 O(n))
2.3 使用场景
由于list它是一个按照插入顺序排序的列表,所以应用场景相对还较多的,例如:
- 消息队列:lpop和rpush(或者反过来,lpush和rpop)能实现队列的功能
- 朋友圈的点赞列表、评论列表、排行榜:lpush命令和lrange命令能实现最新列表的功能,每次通过lpush命令往列表里插入新的元素,然后通过lrange命令读取最新的元素列表。
3 hash(字典)
3.1 数据结构
Redis 中的 Hash和 Java的 HashMap 更加相似,都是数组+链表的结构,当发生 hash 碰撞时将会把元素追加到链表上,值得注意的是在 Redis 的 Hash 中 value 只能是字符串.
3.2 常用命令
hset [key] [field] [value] 新建字段信息 hget [key] [field] 获取字段信息 hdel [key] [field] 删除字段 hlen [key] 保存的字段个数 hgetall [key] 获取指定key 字典里的所有字段和值 (字段信息过多,会导致慢查询 慎用:亲身经历 曾经用过这个这个指令导致线上服务故障) hmset [key] [field1] [value1] [field2] [value2] ...... 批量创建 hincr [key] [field] 对字段值自增 hincrby [key] [field] [number] 对字段值增加number
3.3 使用场景
- 购物车:hset [key] [field] [value] 命令, 可以实现以用户Id,商品Id为field,商品数量为value,恰好构成了购物车的3个要素。
- 存储对象:hash类型的(key, field, value)的结构与对象的(对象id, 属性, 值)的结构相似,也可以用来存储对象。
4 set(集合)
4.1 数据结构
Redis 中的 set和Java中的HashSet 有些类似,它内部的键值对是无序的、唯一 的。它的内部实现相当于一个特殊的字典,字典中所有的value都是一个值 NULL。当集合中最后一个元素被移除之后,数据结构被自动删除,内存被回收。
4.2 常用命令
sadd [key] [value] 向指定key的set中添加元素 smembers [key] 获取指定key 集合中的所有元素 sismember [key] [value] 判断集合中是否存在某个value scard [key] 获取集合的长度 spop [key] 弹出一个元素 srem [key] [value] 删除指定元素
4.3 使用场景
- 好友、关注、粉丝、感兴趣的人集合:
- sinter命令可以获得A和B两个用户的共同好友;
- sismember命令可以判断A是否是B的好友;
- scard命令可以获取好友数量;
- 关注时,smove命令可以将B从A的粉丝集合转移到A的好友集合
- 首页展示随机:美团首页有很多推荐商家,但是并不能全部展示,set类型适合存放所有需要展示的内容,而srandmember命令则可以从中随机获取几个。
- 存储某活动中中奖的用户ID ,因为有去重功能,可以保证同一个用户不会中奖两次。
5 zset(有序集合)
5.1 数据结构
zset也叫SortedSet一方面它是个 set ,保证了内部 value 的唯一性,另方面它可以给每个 value 赋予一个score,代表这个value的排序权重。它的内部实现用的是一种叫作“跳跃列表”的数据结构。
5.2 常用命令
zadd [key] [score] [value] 向指定key的集合中增加元素 zrange [key] [start_index] [end_index] 获取下标范围内的元素列表,按score 排序输出 zrevrange [key] [start_index] [end_index] 获取范围内的元素列表 ,按score排序 逆序输出 zcard [key] 获取集合列表的元素个数 zrank [key] [value] 获取元素再集合中的排名 zrangebyscore [key] [score1] [score2] 输出score范围内的元素列表 zrem [key] [value] 删除元素 zscore [key] [value] 获取元素的score
5.3 使用场景
-
zset 可以用做排行榜,但是和list不同的是zset它能够实现动态的排序,例如: 可以用来存储粉丝列表,value 值是粉丝的用户 ID,score 是关注时间,我们可以对粉丝列表按关注时间进行排序。
-
zset 还可以用来存储学生的成绩, value 值是学生的 ID, score 是他的考试成绩。 我们对成绩按分数进行排序就可以得到他的名次。
6 总结
Redis包含5中类型数据结构,每种的特点和底层数据结构会让我们在开发使用中,更好的选择,总结比较粗浅,日后在完善补充。
这篇关于玩玩Redis系列(二)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-12-27阿里云Redis学习入门指南
- 2024-12-27阿里云Redis入门详解:轻松搭建与管理
- 2024-12-27阿里云Redis学习:新手入门指南
- 2024-12-24Redis资料:新手入门快速指南
- 2024-12-24Redis资料:新手入门教程与实践指南
- 2024-12-24Redis资料:新手入门教程与实践指南
- 2024-12-07Redis高并发入门详解
- 2024-12-07Redis缓存入门:新手必读指南
- 2024-12-07Redis缓存入门:新手必读教程
- 2024-12-07Redis入门:新手必备的简单教程