文章目录

  • 前言
  • 一、Redis的数据结构?
  • 二、string常用方法和使用场景
  • 1.常用方法介绍
  • 2.string使用场景介绍
  • 三、hash常用方法和使用场景
  • 1.hash常用方法
  • 2.hash使用场景
  • 四、list常用方法和使用场景
  • 1.list常用方法
  • 2.list使用场景
  • 五、set常用方法和使用场景
  • 1.set常用方法
  • 2.set使用场景
  • 六、zset常用方法和使用场景
  • 1.zset常用方法
  • 2.zset使用场景
  • 六、总结



前言

今天分享Redis的五种数据结构以及他们在实战中的使用场景


一、Redis的数据结构?

我们都知道Redis是现在大型系统中必不可少的中间件工具。他可以支持高并发的场景,也可以支持分布式锁。这都与他的设计架构和底层的数据结构有离不开的关系。Redis它是一个K,V结构的非关系型数据库。共有5种数据类型。分别是string、hash、list、set、zset。我们所说的数据类型只是Value不同,key都是string类型的。这里我画了一张图。

redis中的几种数据对象是 redis的五种数据类型使用_使用场景


二、string常用方法和使用场景

1.常用方法介绍

#字符串常用操作
set key value						//存储字符串的键值对
mset key value [key value  …]		//批量存储字符串的键值对
setnx key value						//存储一个不存在的字符串的键值对
get key								//根据key获取一个value
mget key [key  …]					//批量获取value
del key [key …]						//删除键
expire key seconds					//设置一个key的过期时间

#原子加减
incr key					//将key中存储的数字值加1操作
decr key					//J将key中存储的数字值减1操作
incrby key increment		//将key中所存储的值加上increment
decrby key decrement		//将key中所存储的值减上decrement

简单演示一下:

redis中的几种数据对象是 redis的五种数据类型使用_数据库_02


redis中的几种数据对象是 redis的五种数据类型使用_数据库_03

2.string使用场景介绍

  • 普通的单值缓存(一般存储用户的token)
    set key value
    get key

redis中的几种数据对象是 redis的五种数据类型使用_redis中的几种数据对象是_04

  • 对象缓存(储存用户信息)
    set user:110:info value(json数据格式)
    mset user:110:name fafa user:110:age 18
  • 分布式锁
    setnx product:10010 true
    del product:10010
    set product:10010 true ex 10 nx


    设置加锁的最大时长为60s,如果60s内还没有完成业务逻辑处理,就释放锁了。当然,实际生产过程中,我们有很多手段防止业务逻辑还没有处理完就释放锁(锁续命,redisson已经实现了),我们这条命令主要是防止程序意外终止而导致死锁。
  • 计数器
    incr

    例如,我的csdn博客文章的查看人数。查看一次下面的数字就加1,数据结构可以这样设计,incr wenzhang:10
  • 分布式系统全局序列号
    incrby pid 10000 //批量生成序列号可以提升性能

三、hash常用方法和使用场景

1.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

2.hash使用场景

  • 对象缓存(如果是缓存对象的多个字段,并且经常修改,用哈希结构比string结构性能更高)
    hmset user {userId}:name fafa {userId}:age 18
  • 购物车场景
    1 用户id 为key
    2 商品id为field
    3 商品数量value
    购物车操作:
    添加商品:hset cart:20 10010 1
    添加数量:hincrby cart:20 10010 10
    商品总数:hlen cart:20
    删除商品:hdel cart:20 10013
    获取购物车所有商品:hgetall cart:20

    命令操作:

四、list常用方法和使用场景

1.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,一直阻塞等待

2.list使用场景

  • 常用的数据结构
    Stack(栈):lpush + lpop 或者 rpush + rpop
    Queue(队列):lpush + rpop 或者 rpush + lpop
    Blocking MQ(阻塞队列):lpush +brpop 或者 rpush + blpop
    栈:

    队列:

    阻塞队列:

  • 我们先看一张图片

    微信订阅号相信大家都应该不陌生吧!这里我订阅了程序员专栏和 java技术江湖两个大咖。只要是我订阅了的人,他们每次发完文章,就把他们文章的id加入到我的列表中,这样,每次进到我的微信的时候,从这个list中再去拿。这就是list的使用场景。例如:
    程序员专栏发文章了,id为 111
    lpush msg:{tuofafaId} 111
    java技术江湖发文章了,文章id为112
    lpush msg:{tuofafaId} 112
    最后获取最新消息或者前几条消息:lrange msg:10 0 4
    操作如下图所示:

五、set常用方法和使用场景

1.set常用方法

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中删除

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中

2.set使用场景

  • 抽奖场景
    抽奖大家平时在生活中肯定都有参与过。过程这里就不详细介绍了。一般抽奖,我们首先肯定要让用户加入到抽奖的集合中,也就是要参与进来。还要提供查看所有参与抽奖的用户,再就是抽奖了。
    加入抽奖:sadd cj user
    查看参与抽奖人:smembers cj
    抽奖:srandmember cj 3 或者使用 spop cj 3 ,两者的区别是前者抽完奖后还留在集合中(还可以继续抽其他奖),后者从集合中已经删除了(不能在参与了其他的奖了)
    加入抽奖:
  • redis中的几种数据对象是 redis的五种数据类型使用_redis_05

  • 查看所有参与抽奖的用户:
  • redis中的几种数据对象是 redis的五种数据类型使用_redis_06

  • 抽奖:
  • redis中的几种数据对象是 redis的五种数据类型使用_使用场景_07

  • 微信微博的点赞



  • 点赞:sadd like:{消息id} {用户id}
    取消点赞:srem like:{消息id} {用户id}
    检查用户是否点过赞:sismember like:{消息id} {用户id}
    获取点赞的用户列表:smembers like:{消息id}
    获取点赞的用户数: scard like:{消息id}
    命令操作如下:
  • redis中的几种数据对象是 redis的五种数据类型使用_redis_08

  • 集合操作
    此外,set还可以完成数学中的集合操作。求一些交集、并集和差集
    我们设计这样一个环境,假设此时有三个集合A、B、C。集合A中有a,b,c。集合B中 b,c,d。集合C中有 c,d,e。
    求集合A,B,C的交集:sinter A B C
    求集合A,B,C的并集:sunion A B C
    求集合A,B,C的差集:sdiff A B C (返回A集合在B和C集合中不存在的元素)
    命令操作如下:
  • redis中的几种数据对象是 redis的五种数据类型使用_数据库_09

  • 集合操作实现微博微信关注模型
    上一张图来说明关注模型
  • redis中的几种数据对象是 redis的五种数据类型使用_数据库_10

  • 这个场景也很常见。这就是我们所说的关注模型。我关注了谁,谁关注了我,我关注的也关注了谁,我们可能认识的人等等都是set的应用场景。例如:
fafa关注的人:fafaSet-->{dt,gxr}
	suosuo关注的人:suoSet-->{dt,gxr,lmm,fafa}
	彭远关注的人:pySet-->{dt,suosuo,lmm,fafa,nn}
	我和suosuo共同关注的人:sinter fafaSet suoSet --->{dt,gxr}
	我关注的人也关注了他(suosuo):
	sismember  dtSet suosuo
	sismember gxrSet suosuo
	这一项可能有点绕,仔细分析还是可以的。我关注的人也关注了suosuo,那就检查一下我关注的人的集合中是否存在suosuo。有就说明关注了,否则就没有关注。
	我可能认识的人:
	sdiff pySet fafaSet --->{suosuo,lmm,fafa,nn}

六、zset常用方法和使用场景

1.zset常用方法

ZADD key score member [[score member]…]	//往有序集合key中加入带分值元素
ZREM key member [member …]				//从有序集合key中删除元素
ZSCORE key member 						//返回有序集合key中元素member的分值
ZINCRBY 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下标的元素

Zset集合操作
ZUNIONSTORE destkey numkeys key [key ...]//并集计算
ZINTERSTORE destkey numkeys key [key …]	 //交集计算

2.zset使用场景

  • zset集合操作实现排行榜

还是通过一张图说明使用场景:

redis中的几种数据对象是 redis的五种数据类型使用_缓存_11



六、总结

Redis的使用场景还是非常丰富的。总结下来也就是缓存、计算和分布式锁。因为这篇文章重点在于Redis数据结构的常用方法和实战场景介绍,所以,对于分布式锁后面还会在单独写一篇文章。