Redis学习——数据结构下
4、集合(集合(set)类型也是用来保存多个的字符串元素,但和列表类型不一样的是,集合中不允许有重复元素,并且集合中的元素是无序的,不能通过索引下标获取元素。)
1、命令
.集合内操作
1、添加元素 sadd key element [element ...]返回结果为添加成功的元素个数。
2、删除元素 srem key element [element ...]返回结果为成功删除元素个数。
3、计算元素个数 scard key
(scard的时间复杂度为O(1),它不会遍历集合所有元素,而是直接用Redis内部的变量)
4、判断元素是否在集合中 sismember key element 如果给定元素element在集合内返回1,反之返回0
5、随机从集合返回指定个数元素 srandmember key [count] [count]是可选参数,如果不写默认为1
6、从集合随机弹出元素 spop key (spop操作可以从集合中随机弹出一个元素,Redis从3.2版本开始,spop也支持[count]参数)
7、获取所有元素 smembers key
(smembers和lrange、hgetall都属于比较重的命令,如果元素过多存在阻塞Redis的可能性,这时候可以使用sscan来完成)
.集合间操作
1、求多个集合的交集 sinter key [key ...]
2、求多个集合的并集 suinon key [key ...]
3、求多个集合的差集 sdiff key [key ...]
4、将交集、并集、差集的结果保存 sinterstore destination key [key ...]
suionstore destination key [key ...]
sdiffstore destination key [key ...]
(集合间的运算在元素较多的情况下会比较耗时,所以Redis提供了上面三个命令(原命令+store)将集合间交集、并集、差集的结果保存在
destination key中,例如下面操作将user:1:follow和user:2:follow两个集合的交集结果保存在user:1_2:inter中,user:1_2:inter本身也是集合类
sinterstore user:1_2:inter user:1:follow user:2:follow
)
2、内部编码
·intset(整数集合):当集合中的元素都是整数且元素个数小于set-max-intset-entries配置(默认512个)时,Redis会选用intset来作为集合的内部实现,从而减少内存的使用。
·hashtable(哈希表):当集合类型无法满足intset的条件时,Redis会使用hashtable作为集合的内部实现。
3、使用场景(集合类型比较典型的使用场景是标签(tag)。)
(例如一个用户可能对娱乐、体育比较感兴趣,另一个用户可能对历史、新闻比较感兴趣,这些兴趣
点就是标签。有了这些数据就可以得到喜欢同一个标签的人,以及用户的共
同喜好的标签,这些数据对于用户体验以及增强用户黏度比较重要。例如一
个电子商务的网站会对不同标签的用户做不同类型的推荐,比如对数码产品
比较感兴趣的人,在各个页面或者通过邮件的形式给他们推荐最新的数码产
品,通常会为网站带来更多的利益)
集合类型的应用场景通常为以下几种
·sadd=Tagging(标签)
·spop/srandmember=Random item(生成随机数,比如抽奖)
·sadd+sinter=Social Graph(社交需求)
5、有序集合
( 有序集合相对于哈希、列表、集合来说会有一点点陌生,但既然叫有序集合,那么它和集合必然有着联系,它保留了集合不能有重复成员的特性,但不同的是,有序集合中的元素可以排序。但是它和列表使用索引下标作为排序依据不同的是,它给每个元素设置一个分数(score)作为排序的依据。有序集合中的元素不能重复,但是score可以重复,就和一个班里的同学学号不能重复,但是考试成绩可以相同。)
1、命令
·集合内
1、添加成员 zadd key score member [score member ...] 返回结果代表成功添加成员的个数。
·Redis3.2为zadd命令添加了nx、xx、ch、incr四个选项:
·nx:member必须不存在,才可以设置成功,用于添加。
·xx:member必须存在,才可以设置成功,用于更新。
·ch:返回此次操作后,有序集合元素和分数发生变化的个数
·incr:对score做增加,相当于后面介绍的zincrby。
·有序集合相比集合提供了排序字段,但是也产生了代价,zadd的时间
复杂度为O(log(n)),sadd的时间复杂度为O(1)。
2、计算成员个数 zcard key
3、计算某个成员的分数 zscore key member
4、计算成员的排名
zrank key member 是从分数从低到高返回排名,zrevrank反之
5、删除成员 zrem key member [member ...] 返回结果为成功删除的个数。
6、增加成员的分数 zincrby key increment member
zincrby user:ranking 9 tom(tom增加了9分)
7、返回指定排名范围的成员
zrange key start end [withscores]
zrevrange key start end [withscores]
(有序集合是按照分值排名的,zrange是从低到高返回,zrevrange反之。)
8、返回指定分数范围的成员
其中zrangebyscore按照分数从低到高返回,zrevrangebyscore反之
9、返回指定分数范围成员个数
zcount key min max
zcount user:ranking 200 221 :返回200到221分的成员的个数
10、删除指定排名内的升序元素
zremrangebyrank key start end :删除第start到第end名的成员
11、删除指定分数范围的成员 zremrangebyscore key min max
zremrangebyscore user:ranking (250 +inf :将250分以上的成员全部删除
·集合间的操作
1、交集 zinterstore destination numkeys key [key ...] [weights weight [weight ...]][aggregate sum|min|max]
这个命令参数较多,下面分别进行说明:
·destination:交集计算结果保存到这个键。
·numkeys:需要做交集计算键的个数。
·key[key...]:需要做交集计算的键。
·weights weight[weight...]:每个键的权重,在做交集计算时,每个键中
的每个member会将自己分数乘以这个权重,每个键的权重默认是1。
·aggregate sum|min|max:计算成员交集后,分值可以按照sum(和)、min(最小值)、max(最大值)做汇总,默认值是sum。
2、并集 zunionstore destination numkeys key [key ...] [weights weight [weight ...]][aggregate sum|min|max]
(该命令的所有参数和zinterstore是一致的,只不过是做并集计算)
2、内部编码
·ziplist(压缩列表):当有序集合的元素个数小于zset-max-ziplist-entries配置(默认128个),同时每个元素的值都小于zset-max-ziplist-value配
置(默认64字节)时,Redis会用ziplist来作为有序集合的内部实现,ziplist可以有效减少内存的使用。
·skiplist(跳跃表):当ziplist条件不满足时,有序集合会使用skiplist作为内部实现,因为此时ziplist的读写效率会下降。
3、使用场景
(
有序集合比较典型的使用场景就是排行榜系统。例如视频网站需要对用
户上传的视频做排行榜,榜单的维度可能是多个方面的:按照时间、按照播
放数量、按照获得的赞数。本节使用赞数这个维度,记录每天用户上传视频
的排行榜。
)
6、键管理
1、单个键管理
针对单个键的命令,前面几节已经介绍过一部分了,例如type、del、object、exists、expire等,下面将介绍剩余的几个重要命令。
1、键重命名 rename key newkey (如果newKey已经存在,值也会被覆盖)
(为了防止被强行rename,Redis提供了renamenx命令,确保只有newKey
不存在时候才被覆盖,例如下面操作renamenx时,newkey=python已经存在,
返回结果是0代表没有完成重命名,所以键java和python的值没变)
在使用重命名命令时,有两点需要注意:
·由于重命名键期间会执行del命令删除旧的键,如果键对应的值比较大,会存在阻塞Redis的可能性,这点不要忽视。
·如果rename和renamenx中的key和newkey如果是相同的,在Redis3.2和之前版本返回结果略有不同。
2、随机返回一个键 randomkey
3、键过期
除了expire、ttl命令以外,Redis还提供了expireat、pexpire、pexpireat、pttl、persist等一系列命令,下面分别进行说明:
·expire key seconds:键在seconds秒后过期。
·expireat key timestamp:键在秒级时间戳timestamp后过期。
ttl命令和pttl都可以查询键的剩余过期时间,但是pttl精度更高可以达到毫秒级别,有3种返回值:
·大于等于0的整数:键剩余的过期时间(ttl是秒,pttl是毫秒)。
·-1:键没有设置过期时间。
·-2:键不存在。
·pexpire key milliseconds:键在milliseconds毫秒后过期。
·pexpireat key milliseconds-timestamp键在毫秒级时间戳timestamp后过期。
在使用Redis相关过期命令时,需要注意以下几点。
1)如果expire key的键不存在,返回结果为0
2)如果过期时间为负值,键会立即被删除,犹如使用del命令一样
3)persist命令可以将键的过期时间清除
4)对于字符串类型键,执行set命令会去掉过期时间,这个问题很容易在开发中被忽视。
5)Redis不支持二级数据结构(例如哈希、列表)内部元素的过期功能,例如不能对列表类型的一个元素做过期时间设置。
6)setex命令作为set+expire的组合,不但是原子执行,同时减少了一次网络通讯的时间
4、迁移键
(
迁移键功能非常重要,因为有时候我们只想把部分数据由一个Redis迁移到另一个Redis(例如从生产环境迁移到测试环境),Redis发展历程中提
供了move、dump+restore、migrate三组迁移键的方法,它们的实现方式以及使用的场景不太相同,下面分别介绍
)
(1)move: move key db
move命令用于在Redis内部进行数据迁移,Redis内部可以有多个数据库,彼此在数据上是相互隔离的,move key db就
是把指定的键从源数据库移动到目标数据库中,多数据库功能不建议在生产环境使用,所以这个命令读者知道即可。
(2)dump+restore
dump key
restore key ttl value
dump+restore可以实现在不同的Redis实例之间进行数据迁移的功能,整个迁移的过程分为两步:
1)在源Redis上,dump命令会将键值序列化,格式采用的是RDB格式。
2)在目标Redis上,restore命令将上面序列化的值进行复原,其中ttl参数代表过期时间,如果ttl=0代表没有过期时间。
有关dump+restore有两点需要注意:
第一,整个迁移过程并非原子性的,而是通过客户端分步完成的。
第二,迁移过程是开启了两个客户端连接,所以dump的结果不是在源Redis和目标Redis之间进行传输
(3)migrate
migrate host port key|"" destination-db timeout [copy] [replace] [keys key [key
migrate命令也是用于在Redis实例间进行数据迁移的,实际上migrate命令就是将dump、restore、del三个命令进行组合,从而简化了操作流程。
migrate命令具有原子性,而且从Redis3.0.6版本以后已经支持迁移多个键的
功能,有效地提高了迁移效率,migrate在10.4节水平扩容中起到重要作用。
2、遍历键(Redis提供了两个命令遍历所有的键,分别是keys和scan)
1.全量遍历键 keys pattern (pattern使用的是glob风格的通配符)
·*代表匹配任意字符。
·代表匹配一个字符。
·[]代表匹配部分字符,例如[1,3]代表匹配1,3,[1-10]代表匹配1到10的任意数字。
·\x用来做转义,例如要匹配星号、问号需要进行转义
如果Redis包含了大量的键,执行keys命令很可能会造成Redis阻塞,所以一般建议不要在生
产环境下使用keys命令。但有时候确实有遍历键的需求该怎么办,可以在以下三种情况使用:
·在一个不对外提供服务的Redis从节点上执行,这样不会阻塞到客户端的请求,但是会影响到主从复制。
·如果确认键值总数确实比较少,可以执行该命令。
·使用下面要介绍的scan命令渐进式的遍历所有键,可以有效防止阻塞。
2.渐进式遍历:scan cursor [match pattern] [count number]
Redis从2.8版本后,提供了一个新的命令scan,它能有效的解决keys命令存在的问题。和keys命令执行时会遍历所有键不同,scan采用渐进式遍历
的方式来解决keys命令可能带来的阻塞问题,每次scan命令的时间复杂度是O(1),但是要真正实现keys的功能,需要执行多次scan。
scan cursor [match pattern] [count number]各参数含义:
·cursor是必需参数,实际上cursor是一个游标,第一次遍历从0开始,每次scan遍历完都会返回当前游标的值,直到游标值为0,表示遍历结束。
·match pattern是可选参数,它的作用的是做模式的匹配,这点和keys的模式匹配很像。
·count number是可选参数,它的作用是表明每次要遍历的键个数,默认值是10,此参数可以适当增大。
(
除了scan以外,Redis提供了面向哈希类型、集合类型、有序集合的扫
描遍历命令,解决诸如hgetall、smembers、zrange可能产生的阻塞问题,对
应的命令分别是hscan、sscan、zscan,它们的用法和scan基本类似。
)
**渐进式遍历可以有效的解决keys命令可能产生的阻塞问题,但是scan并
非完美无瑕,如果在scan的过程中如果有键的变化(增加、删除、修改),
那么遍历效果可能会碰到如下问题:新增的键可能没有遍历到,遍历出了重
复的键等情况,也就是说scan并不能保证完整的遍历出来所有的键,这些是我们在开发时需要考虑的。
7、数据库管理(Redis提供了几个面向Redis数据库的操作,它们分别是dbsize、select、flushdb/flushall命令)
1.切换数据库(Redis是用数字作为多个数据库的实现。Redis默认配置中是有16个数据库)
select dbIndex
2.flushdb/flushall
flushdb/flushall命令用于清除数据库,两者的区别的是flushdb只清除当前数据库,flushall会清除所有数据库。
flushdb/flushall命令可以非常方便的清理数据,但是也带来两个问题:
·flushdb/flushall命令会将所有数据清除,一旦误操作后果不堪设想。
·如果当前数据库键值数量比较多,flushdb/flushall存在阻塞Redis的可能性。
参考资料:《Redis开发与运维》
Redis学习——数据结构下的更多相关文章
- Redis学习——数据结构介绍(四)
一.简介 作为一款key-value 的NoSQL数据库,Redis支持的数据结构比较丰富,有:String(字符串) .List(列表) .Set(集合) .Hash(哈希) .Zset(有序集合) ...
- Redis学习——数据结构上
一.常用的全局命令 1.查看所有的键: KEYS * KEYS pattern:查找所有符合给定模式 pattern 的 key . KEYS 的速度非常快,但在一个大的数据库中使用它仍然可能造成性能 ...
- Redis学习---Ubuntu下Redis的安装
Ubuntu系统安装 Linux 系统安装[Ubuntu] 安装/启动Redis 要在 Ubuntu 上安装 Redis,打开终端,然后输入以下命令: 升级软件管理模块apt: sudo apt-ge ...
- Redis学习---基础学习[all]
什么是NoSQL型数据库 NoSQL数据库---NoSQL数据库的分类 Redis学习---NoSQL和SQL的区别及使用场景 Redis学习---负载均衡的原理.分类.实现架构,以及使用场景 什么是 ...
- Redis学习笔记一:数据结构与对象
1. String(SDS) Redis使用自定义的一种字符串结构SDS来作为字符串的表示. 127.0.0.1:6379> set name liushijie OK 在如上操作中,name( ...
- redis学习(二) redis数据结构介绍以及常用命令
redis数据结构介绍 我们已经知道redis是一个基于key-value数据存储的数据结构数据库,这里的key指的是string类型,而对应的value则可以是多样的数据结构.其中包括下面五种类型: ...
- (转)NoSQL——Redis在win7下安装配置的学习一
NoSQL——Redis在win7下安装配置的学习一 有些也是从网上看来的 1.下载安装 Redis它没有windows的官方版本,但是又非官方的版本,到官网上去下载相应的版本,我的电脑是win7 ...
- Redis学习笔记之Redis中5种数据结构的使用场景介绍
原来看过 redisbook 这本书,对 redis 的基本功能都已经熟悉了,从上周开始看 redis 的源码.目前目标是吃透 redis 的数据结构.我们都知道,在 redis 中一共有5种数据结构 ...
- 大数据技术之_16_Scala学习_08_数据结构(下)-集合操作+模式匹配
第十一章 数据结构(下)-集合操作11.1 集合元素的映射-map11.1.1 map 映射函数的操作11.1.2 高阶函数基本使用案例1+案例211.1.3 使用 map 映射函数来解决11.1.4 ...
随机推荐
- MindArmour差分隐私
MindArmour差分隐私 总体设计 MindArmour的Differential-Privacy模块,实现了差分隐私训练的能力.模型的训练主要由构建训练数据集.计算损失.计算梯度以及更新模型参数 ...
- 从PyTorch到ONNX的端到端AlexNet
从PyTorch到ONNX的端到端AlexNet 这是一个简单的脚本,可将Torchvision中定义的经过预训练的AlexNet导出到ONNX中.运行一轮推理Inference,然后将生成的跟踪模型 ...
- ARM Cortex-M嵌入式C基础编程(下)
ARM Cortex-M嵌入式C基础编程(下) ARM Cortex-M Embedded C Fundamentals/Tutorial -Aviral Mittal Load Region Vs ...
- 如何使用Nsight System?
如何使用Nsight System?
- python应用_读取Excel数据列表输出【一】
python能使用xlrd模块实现对Excel数据的读取,且按照想要的输出形式. 1.准备Excel数据如下: 2.下面主要是对Excel数据读取后以双列表(每一行是一个用例为一个列表,再一个个案例组 ...
- 再看 Java 中的单例
此前面试遇到了单例问题,本以为已经背的滚瓜烂熟,没想到被问单例如何避免被反射和序列化破坏,虽然后来还是等到了通知,但还是复习一下单例的实现方式,并学习防止反射和序列化破坏的手段. 基本实现方式 其他相 ...
- UF_LAYER 图层操作
Open C uc5007uc5008uc5009UF_LAYER_ask_category_infoUF_LAYER_ask_category_tagUF_LAYER_ask_statusUF_LA ...
- 把axios获取到的数据渲染到列表上,使用better-scroll实现列表左右滑动
问题:axios数据请求完后,页面是有数据的,即页面看到有数据,但是better-scroll却无法滚动 原因:这是因为在数据更新前,better-scroll已经渲染完成了 解决方法:这是个异步问题 ...
- Spring Boot WebFlux-09——WebFlux 集成测试及部署
第09课:WebFlux 集成测试及部署 前言 在日常工作中,免不了自测 UT,因为覆盖率不达标,是不允许提交测试,那怎么进行 WebFlux 项目的测试呢.@WebFluxTest 是 WebFlu ...
- 深入理解JVM,7种垃圾收集器,看完我跪了
如果说收集算法是内存回收的方法论,那么垃圾收集器就是内存回收的具体实现.Java虚拟机规范中对垃圾收集器应该如何实现并没有任何规定,因此不同的厂商.版本的虚拟机所提供的垃圾收集器都可能会有很大差别,并 ...