首页 / REDIS / 玩玩Redis系列(二)
玩玩Redis系列(二)
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了玩玩Redis系列(二),小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含7792字,纯文字阅读大概需要12分钟。
内容图文
![玩玩Redis系列(二)](/upload/InfoBanner/zyjiaocheng/859/656a668133184fe7890e42e295bdac87.jpg)
玩玩Redis系列二
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系列(二)全部内容,希望文章能够帮你解决玩玩Redis系列(二)所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。