博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
redis数据类型以应用场景
阅读量:4142 次
发布时间:2019-05-25

本文共 6411 字,大约阅读时间需要 21 分钟。

一、数据类型

1. 字符串(string)
1)概念	(1)Redis中的字符串是一个字节序列。Redis中的字符串是二进制安全的,这意味着它们的长度不由任何特殊的终止字符决定。因此,可以在一个字符串中存储高达512兆字节的任何内容	(2)String在redis内部存储默认就是一个字符串,被redisObject所引用,当遇到incr,decr等操作时会转成数值型进行计算,此时redisObject的encoding字段为int2)常见操作	(1)set key value  	设置key的值	(2)get key            获取key的值3)应用场景	(1)常规key-value缓存应用。常规计数: 微博数, 粉丝数
2. 散列/哈希(hash)题
1)概念	(1)Redis散列/哈希(Hashes)是键值对的集合。Redis散列/哈希是字符串字段和字符串值之间的映射。因此,它们用于表示对象	(2)每个散列/哈希可以存储多达2^32 - 1个健-值对(超过40亿个)	(3)Redis Hash对应Value内部实际就是一个HashMap,实际这里会有2种不同实现,这个Hash的成员比较少时Redis为了节省内存会采用类似一维数组的方式来紧凑存储,而不会采用真正的HashMap结构,对应的value redisObject的encoding为zipmap,当成员数量增大时会自动转成真正的HashMap,此时encoding为ht2) 常见操作(加m表示可以罗列多个值,比如hmget)	(1)hmset key mapkey1 value1 mapkey2 value2           设置hash对象各个字段的值	(2)hset key mapkey value                             设置单个字段的值	(3)hgetall                                           获取整个hash对象	(4)hget mapkey1                                      获取指定字段的值	(5)HAVLS key                                         获取hash中的所有值(不包括mapkey) 	(6)hdel key mapkey                                   删除指定mapkey	(7)hexists key mapkey                                判断指定mapkey是否存在		3)应用场景	(1)存储部分变更数据,如用户信息等
3. 列表(list)
1)概念	(1)Redis列表只是字符串列表,按插入顺序排序。您可以向Redis列表的头部或尾部添加元素		(2)列表的最大长度为2^32 - 1个元素(4294967295,每个列表可容纳超过40亿个元素)	(3)Redis的list是每个子元素都是String类型的双向链表,可以通过push和pop操作从列表的头部或者尾部添加或者删除元素,这样List即可以作为栈,也可以作为队列2)常见操作	(1)lpush key value [value2...]                        插入数据(插入的数据永远在左边)	(2)lrange key begin end                               获取指定范围的数据	(3)lpop  key                                          删除并获取列表中的第一个元素	(4)lindex key index                                   通过其索引从列表获取元素3)应用场景	(1)Redis链表经常会被用于消息队列的服务,以完成多程序之间的消息交换。假设一个应用程序正在执行LPUSH操作向链表中添加新的元素,我们通常将这样的程序称之为"生产者(Producer)",而另外一个应用程序正在执行RPOP操作从链表中取出元素,我们称这样的程序为"消费者(Consumer)"		(2)比如twitter的关注列表,粉丝列表等都可以用Redis的list结构来实现	(3)使用list可以构建队列系统,使用sorted set甚至可以构建有优先级的队列系统	(4)将Redis用作日志收集器:实际上还是一个队列,多个端点将日志信息写入Redis,然后一个worker统一将所有日志写到磁盘	(5)记录前N个最新登陆的用户Id列表,超出的范围可以从数据库中获得
4. 集合(set)
1)概念	(1)Redis集合是唯一字符串的无序集合	(2)set 的内部实现是一个 value永远为null的HashMap,实际就是通过计算hash的方式来快速排重的,这也是set能提供判断一个成员是否在集合内的原因2)常见操作	(1)sadd key value     插入数据	(2)smembers key       获取集合的数据   3)应用场景:	(1)可以使用Redis的Set数据类型跟踪一些唯一性数据,比如访问某一博客的唯一IP地址信息。对于此场景,我们仅需在每次访问该博客时将访问者的IP存入Redis中,Set数据类型会自动保证IP地址的唯一性	2)充分利用Set类型的服务端聚合操作方便、高效的特性,可以用于维护数据对象之间的关联关系。比如所有购买某一电子设备的客户ID被存储在一个指定的Set中,而购买另外一种电子产品的客户ID被存储在另外一个Set中,如果此时我们想获取有哪些客户同时购买了这两种商品时,Set的intersections命令就可以充分发挥它的方便和效率的优势了		3)在微博应用中,可以将一个用户所有的关注人存在一个集合中,将其所有粉丝存在一个集合。Redis还为集合提供了求交集、并集、差集等操作,可以非常方便的实现如共同关注、共同喜好、二度好友等功能,对上面的所有集合操作,你还可以使用不同的命令选择将结果返回给客户端还是存集到一个新的集合中	4)获取某段时间所有数据去重值:这个使用Redis的set数据结构最合适了,只需要不断地将数据往set中扔就行了,set意为集合,所以会自动排重
5. 可排序集合(sorted set)
1)概念	(1)Redis可排序集合类似于Redis集合,是不重复的字符集合。 不同之处在于,排序集合的每个成员都与分数相关联,这个分数用于按最小分数到最大分数来排序的排序集合		(2)虽然成员是唯一的,但分数值可以重复	(3)集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)	(4)Redis sorted set的内部使用HashMap和跳跃表(SkipList)来保证数据的存储和有序,HashMap里放的是成员到score的映射,而跳跃表里存放的是所有的成员,排序依据是HashMap里存的score,使用跳跃表的结构可以获得比较高的查找效率,并且在实现上比较简单2)常见操作	1)zadd key index value	                                 插入数据	2)zrange key begin end withscores                       获取指定分数值的数据	3)应用场景:	1)可以用于一个大型在线游戏的积分排行榜。每当玩家的分数发生变化时,可以执行ZADD命令更新玩家的分数,此后再通过ZRANGE命令获取积分TOP TEN的用户信息。当然我们也可以利用ZRANK命令通过username来获取玩家的排行信息。最后我们将组合使用ZRANGE和ZRANK命令快速的获取和某个玩家积分相近的其他用户的信息	2)Sorted-Sets类型还可用于构建索引数据	3)当你需要一个有序的并且不重复的集合列表,那么可以选择sorted set数据结构,比如twitter 的public timeline可以以发表时间作为score来存储,这样获取时就是自动按时间排好序的	4)另外还可以用Sorted Set来做带权重的队列,比如普通消息的score为1,重要消息的score为2,然后工作线程可以选择按score的倒序来获取工作任务。让重要的任务优先执行

二、常见redis命令

1. 查询键相关
1)exists key             			判断某个键是否存在(存在返回1,不存在返回0)2)keys pattern           			找指定匹配表达式的键(不能跨集群)3)type key                      	返回存储在键中的值的数据类型
2. 更改键相关
1)del key                			删除指定键(如果键被删除,则命令的输出将为(integer) 1,否则为(integer) 0)2)rename key newKey      			修改键的名字
3. 时间相关(加p是毫秒级)
1)expire key seconds            	设置key的过期时间2)expireat key timestamp        	设置在指定时间戳之后键到期/过期。这里的时间是Unix时间戳格式           3) ttl key                       	获取key的过期时间(永久返回-1,key不存在返回-2)
4. 其他
1)randomkey                     	获取一个随机的key

三、redis的应用场景

1. 显示最新的项目列表(list)
1)比如说,我们的一个Web应用想要列出用户贴出的最新20条评论。在最新的评论边上我们有一个“显示全部”的链接,点击后就可以获得更多的评论2)我们假设数据库中的每条评论都有一个唯一的递增的ID字段3)我们可以使用分页来制作主页和评论页,使用Redis的模板,每次新评论发表时,我们会将它的ID添加到一个Redis列表:LPUSH latest.comments 
4)我们将列表裁剪为指定长度,因此Redis只需要保存最新的5000条评论:LTRIM latest.comments 0 5000 5)每次我们需要获取最新评论的项目范围时,我们调用一个函数来完成 (1)先从redis里面拿取到这5000个id加评论 (2)如果超过5000,再从数据库里面拿 (3)SQL数据库(或是硬盘上的其他类型数据库)只是在用户需要获取“很远”的数据时才会被触发,而主页或第一个评论页是不会麻烦到硬盘上的数据库了
2. 排行榜应用,取TOP N操作 (zset)
1)取最新N个数据的操作以时间为权重,这个是以某个条件为权重,比如按顶的次数排序,这时候就需要我们的sorted set出马了,将你要排序的值设置成sorted set的score,将具体的数据设置成相应的value,每次只需要执行一条ZADD命令即可2)热门,排行榜应用	zadd login:login_times 5 1	zadd login:login_times 1 2	zadd login:login_times 2 3								// 将登录次数和用户统一存储在一个sorted set里	ret = r.zincrby("login:login_times", 1, uid)            // 当用户登录时,对该用户的登录次数自增1	ret = r.zrevrange("login:login_times", 0, N-1) 			// 那么如何获得登录次数最多的用户呢,逆序排列取得排名前N的用户3)列出前100名高分选手		(1)每次获得新得分时               ZADD leaderboard  
(2)得到前100名高分用户很简单 ZREVRANGE leaderboard 0 99
3. 删除与过滤(list)
1)我们可以使用LREM来删除评论。如果删除操作非常少,另一个选择是直接跳过评论条目的入口,报告说该评论已经不存在2)有些时候你想要给不同的列表附加上不同的过滤器。如果过滤器的数量受到限制,你可以简单的为每个不同的过滤器使用不同的Redis列表。毕竟每个列表只有5000条项目,但Redis却能够使用非常少的内存来处理几百万条项目
4. 按照用户投票和时间排序(zset)
1)新闻按照类似下面的公式根据得分来排序:score = points / time^alpha 因此用户的投票会相应的把新闻挖出来,但时间会按照一定的指数将新闻埋下去	2)模式是这样的,开始时先观察那些可能是最新的项目,例如首页上的1000条新闻都是候选者,因此我们先忽视掉其他的,这实现起来很简单。每次新的新闻贴上来后,我们将ID添加到列表中,使用LPUSH + LTRIM,确保只取出最新的1000条项目3)有一项后台任务获取这个列表,并且持续的计算这1000条新闻中每条新闻的最终得分4)计算结果由ZADD命令按照新的顺序填充生成列表,老新闻则被清除。这里的关键思路是排序工作是由后台任务来完成的
5. 处理过期项目(zset)题
1)另一种常用的项目排序是按照时间排序。我们使用unix时间作为得分即可2)每次有新项目添加到我们的非Redis数据库时,我们把它加入到排序集合中。这时我们用的是时间属性,current_time和time_to_live3)另一项后台任务使用ZRANGE…SCORES查询排序集合,取出最新的10个项目。如果发现unix时间已经过期,则在数据库中删除条目
6. 计数
1)Redis是一个很好的计数器,这要感谢INCRBY和其他相似命令2)你可以计算出最近用户在页面间停顿不超过60秒的页面浏览量,当计数达到比如20时,就可以显示出某些条幅提示,或是其它你想显示的东西
7. 特定时间内的特定项目
1)另一项对于其他数据库很难,但Redis做起来却轻而易举的事就是统计在某段特点时间里有多少特定用户访问了某个特定资源2)比如我想要知道某些特定的注册用户或IP地址,他们到底有多少访问了某篇文章	(1)每次我获得一次新的页面浏览时我只需要这样做             SADD page:day1:
(2)当然你可能想用unix时间替换day1,比如time()-(time()%3600*24)等等。 想知道特定用户的数量吗?只需要使用 SCARD page:day1:
(3)需要测试某个特定用户是否访问了这个页面 SISMEMBER page:day1:
8. 查找某个值所在的区间(区间无重合) :(Sorted Set) / 交集,并集,差集:(Set)

参考网址

注:文章是经过参考其他的文章然后自己整理出来的,有可能是小部分参考,也有可能是大部分参考,但绝对不是直接转载,觉得侵权了我会删,我只是把这个用于自己的笔记,顺便整理下知识的同时,能帮到一部分人。

ps : 有错误的还望各位大佬指正,小弟不胜感激

你可能感兴趣的文章
【JAVA数据结构】先进先出队列
查看>>
Objective-C 基础入门(一)
查看>>
Flutter Boost的router管理
查看>>
C++模板
查看>>
【C#】如何实现一个迭代器
查看>>
【C#】利用Conditional属性完成编译忽略
查看>>
VUe+webpack构建单页router应用(一)
查看>>
(python版)《剑指Offer》JZ01:二维数组中的查找
查看>>
Spring MVC中使用Thymeleaf模板引擎
查看>>
深入了解php底层机制
查看>>
PHP中的stdClass 【转】
查看>>
XHProf-php轻量级的性能分析工具
查看>>
OpenCV gpu模块样例注释:video_reader.cpp
查看>>
就在昨天,全球 42 亿 IPv4 地址宣告耗尽!
查看>>
Mysql复制表以及复制数据库
查看>>
Linux分区方案
查看>>
如何使用 systemd 中的定时器
查看>>
git命令速查表
查看>>
linux进程监控和自动重启的简单实现
查看>>
OpenFeign学习(三):OpenFeign配置生成代理对象
查看>>