Redis学习笔记一、数据类型

数据类型

1. 概述

  Redis(Remote Dictionary Server)是速度非常快的非关系型(NOSQL)内存键值数据库。Redis支持物质基本数据类型String、Hash、List、Set、ZSet。
String、Hash、List、Set、ZSet。

2. 五种数据类型

  键的类型只能是字符串;值支持五种数据类型:String、Hash、List、Set、ZSet。

2.1. String --字符串

  String 数据结构是简单的 key-value 类型,value 不仅可以是 String,也可以是数字。
  应用场景: 常规key-value缓存应用。单值缓存,对象缓存,分布式锁。

# 1. 单值缓存
SET KEY value
GET KEY

# 2. 对象缓存
SET user:1 value(json格式数据)
# 用户的name一般不会变化,余额会经常发生变化,这时会用到批量处理的命令
MSET user:1:name hyk user:1:balance 1888
MGET user:1:name user:1:balance

# 3. 分布式锁
SETNX product:10001 true			// 返回1,代表获取锁成功
SETNX product:10001 false			// 返回0,代表获取锁失败
...执行业务逻辑
DEL product:10001					// 执行完业务,释放锁
SET product:10001 true ex 10 nx		// 防止程序意外终止,导致死锁

   案例: 计数器,分布式系统全局序列号

# 使用场景一、 计数器
# 每次打开,都执行一次命令 INCR article:readcount:{文章ID}
redis 127.0.0.1:6379> INCR article:readcount:1001
redis 127.0.0.1:6379> GET article:readcount:1001

# 使用场景二、 分布式系统全局序列号
# 分库、分表的集群环境下设置id自增会有问题,可以借助redis实现分布式系统全局序列号,由redis统一管理id自增
# 这种方式会导致热点key的压力非常大,比如高并发的订单表会让redis压力很大。
redis 127.0.0.1:6379> INCRBY orderId
# 上面这种方式,会使得系统和redis交互过多,可以每次去redis获取1000
redis 127.0.0.1:6379> INCRBY orderId 1000

2.2. Hash – 字典

  Redis hash 是一个 string 类型的 field 和 value 的映射表,hash相比stringl更适合用于存储对象。
  常用命令:hget,hset,hgetallhmset,hmget等。

  应用场景: 对象信息存储

	HMSET user {userid}:name hyk {userid}:balance 1888
	HMSET user 1:name hyk 1:balance 1888
	HMGET user 1:name 1:balance

  Redis中有一个经典的Big Key限制,如果user表中有几百万条数据,通过user 这个key一下取出几百万条数据是很慢的,会对数据进行分组存储,一个user一般不会超过1000条数据。

  案例: 购物车

	# 用户id为key,商品id为field,商品数量为value
	
	# 添加商品
	HSET cart:0001 00001 1
	
	# 增加商品数量
	HINCRBY cart:0001 00001 1
	
	# 商品总数
	HLEN cart:0001
	
	# 删除商品
	HDEL cart:0001 00001
	
	# 获取购物车中所有商品
	HGETALL cart:0001

2.3. List – 列表

  列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。
  常用命令:LPUSH,RPUSH,LPOP,RPOP 等。

  应用场景: 常用数据结构,关注列表,粉丝列表

	# 常用数据结构(栈,队列,阻塞队列)
	Stack = LPUSH + LPOP
	Queue = LPUSH + RPOP
	Blocking MQ = LPUSH + BRPOP # BRPOP从key列表表尾弹出一个元素,如果列表中没有会一直阻塞等待,也可以设置超时时间

  案例: 微博和微信公众号消息流(最后发的动态显示在最开始)

	# 我的id 000, 我关注的001发了推文00001,我关注的002发了推文00002
	LPUSH 000 00001
	LPUSH 000 00002
	LRANGE 000 0 4 		# 左闭右闭,List已经进行了排序,省去了排序的时间

2.4. Set – 集合

  底层使用了intset和hashtable两种数据结构存储的,intset我们可以理解为数组,hashtable就是普通的哈希表。
  常用命令:SADD,SMEMBERS,SREM

  应用场景:
  在微博应用中,可以将一个用户所有的关注人存储在一个集合中,将其所有粉丝存在一个集合。因为 Redis 非常人性化的为集合提供了求交集、并集、差集等操作,那么就可以非常方便的实现如共同关注、共同喜好、二度好友等功能。
1.共同好友、二度好友
2. 利用唯一性,可以统计访问网站的所有独立 IP
3. 好友推荐的时候,根据 tag 求交集,大于某个 threshold 就可以推荐

  案例: 微信抽奖小程序,微信微博点赞收藏标签

# 五个人参与抽奖
SADD act:01 001
SADD act:01 002
SADD act:01 003
SADD act:01 004
SADD act:01 005
# 查看参与act01的成员
SMEMBERS act:01
# 从act01中随机选出2个,不会从集合中删除
SRANDMEMBER act:01 2
# 从act01中随机选出2个,会从集合中删除
SPOP act:01 2

# 点赞
SADD like:0001 001
# 取消点赞
SREM like:0001 001
# 检查用户是否点过赞
SISMEMBER like:001 001
# 获取点赞的用户列表
SMEMBERS like:0001
# 获取点赞用户数
SCARD like:0001

2.5. ZSet – 有序集合

  Sorted Set是将Set中的元素增加了一个权重参数score。比如一个存储成绩的Sorted Set,value可以是学号,score就可以是考试得分,这样数据插入集合时就进行了一个天然的排序。
  常用命令:ZADD,ZREM,ZCARD

  还可以用 Sorted Sets 来做带权重的队列,比如普通消息的 score 为1,重要消息的 score 为2,然后工作线程可以选择按 score 的倒序来获取工作任务。让重要的任务优先执行。

  应用场景:

  1. 带有权重的元素,比如一个游戏的用户得分排行榜
  2. 班级成绩,工资表排序
  3. 排行榜实现

  案例: 热度排行榜(热搜)

# 点击新闻
ZINCRBY hotNews:20190819 1 守护香港
# 展示当日排行前十
ZREVARANGE hotNews:20190819 0 9 WITHSCORES
# 七日搜索排行榜单计算
ZUNIONSTORE hotNews:20190813-20190819 7 hotNews:20190813 20190814 20190815 ...  20190819
# 展示七日排行前十
ZREVRANGE hotNews:20190813-20190819 0 9 WITHSCORES

3. 跳表

  跳跃表是一种有序的数据结构,它通过在每个节点中维持多个指向其他的节点指针,从而达到快速访问队尾目的。跳跃表的效率可以和平衡树想媲美了,最关键是它的实现相对于平衡树来说,代码的实现上简单。

应用场景:

  1. 是有序集合的底层实现之一。

3.1. 跳表结构

  跳跃表受到多层链表结构的启发。上面每一层链表的节点个数,是下面一层的节点个数的一半,这样查找过程就非常类似于一个二分查找,使得查找的时间复杂度可以降低到 O(logn)

  这种方法在插入数据的时候有很大的问题。新插入一个节点之后,就会打乱上下相邻两层链表上节点个数严格的 2:1 的对应关系。如果要维持这种对应关系,就必须把新插入的节点后面的所有节点 (也包括新插入的节点) 重新进行调整,这会让时间复杂度重新蜕化成O(n)。删除数据也有同样的问题。

  为了避免这一问题,它不要求上下相邻两层链表之间的节点个数有严格的对应关系,而是 为每个节点随机出一个层数(level)。比如,一个节点随机出的层数是 3,那么就把它链入到第 1 层到第 3 层这三层链表中。
在这里插入图片描述
  https://blog.csdn.net/weixin_41622183/article/details/91126155

3.2. 插入数据

  https://blog.csdn.net/weixin_41622183/article/details/91126155

3.3. 查找数据

在这里插入图片描述

  https://blog.csdn.net/weixin_41622183/article/details/91126155

3.4. 与红黑树等平衡二叉树对比

  • 插入速度非常快速,因为不需要进行旋转等操作来维护平衡性;
  • 更容易实现;
  • 支持无锁操作。

4. 参考文献

[1] 黄健宏.Redis设计与实现[M].北京:机械工业出版社

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值