ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

玩玩Redis系列(二)

2021-04-25 17:58:00  阅读:172  来源: 互联网

标签:SET 系列 1.2 Redis value 列表 玩玩 key 数据结构


玩玩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中类型数据结构,每种的特点和底层数据结构会让我们在开发使用中,更好的选择,总结比较粗浅,日后在完善补充。

标签:SET,系列,1.2,Redis,value,列表,玩玩,key,数据结构
来源: https://blog.csdn.net/goodjobman/article/details/116133642

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有