Redis基础2

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: Redis基础

Redis基础1:https://developer.aliyun.com/article/1521821

set数据类型

SET类型:用于保存多个字符串类型的元素(集合类型),但是要求存储的元素不能重复(唯一性),并且存储的元素是无序的(与list数据类型对应)

SADD:将一个或者多个元素添加到set中(重复的元素无法添加)


语法格式:SADD key member [member…]


时间复杂度:O(1)


返回值:成功添加的元素的个数


SMEMBERS:获取Set中的所有元素,但是元素间的顺序是无序的


语法格式:SMEMBERS key


时间复杂度:O(1)


返回值:set中的所有元素或者nil


SISMEMBER:判断元素是否在set中


语法格式:SISMEMBER key member


时间复杂度:O(1)


返回值:1表示存在,0表示不存在


SPOP:随机删除set中的元素


语法格式:SPOP key count (count可省略,表示删除元素的个数)


时间复杂度:O(1)


返回值:成功删除的元素个数


SMOVE:从元素从一个set移动到另一个set中


语法格式:SMOVE source destination member (如果目标set中已存在要移动的元素,任然会成功移动只是没有实际效果)


时间复杂度:O(1)


返回值:1表示移动成功,0表示移动失败(如果要移动的元素在source中不存在,就会移动失败返回0)


SREM:删除set中的元素


语法格式:SREM key member [member …] (可以一次删除一个或多个元素)


时间复杂度:O(1)


返回值:成功删除的元素个数


集合间操作:交集、并集以及差集


SINTER:获取给定的set之间的交集


语法格式:SINTER key [key …]


时间复杂度:O(N*M) N是最小的集合的元素个数,M是最大的集合的元素个数


返回值:交集中的元素


SINTERSTORE: 将set之间的交集存储到 destination


语法格式:SINTERSTORE destination key [key …]


时间复杂度:O(N*M)


返回值:交集的元素个数


SUNION:获取给定的set之间的并集


语法格式:SUNION key [key …]


时间复杂度:O(N) N指的是总的元素个数(所有key的元素个数之和)


返回值:并集中的元素


SUNIONSTORE:将set之间的并集存储到 destination


语法格式:SUNIONSTORE key [key …]


时间复杂度:O(N)


返回值:并集中的元素个数


SDIFF:获取给定的set之间的差集(差集结果与key的顺序有关)


语法格式:SDIFF key [key …]


时间复杂度:O(N) N指的是总的元素个数


返回值:差集中的元素


SDIFFSTORE:将set之间的差集存储到distination中


语法格式:SDIFFSTORE destination key [key …]


时间复杂度:O(N*M)


返回值:差集中的元素个数


集合类型的内部编码:


Insert(整数集合):当元素个数小于set-max-intset-entries配置(默认512)时,Redis会使用intset来作为集合的内部实现从而节省内存


Hashtable(哈希表):当集合类型无法满足intset的条件时,Redis就会使用hashtable作为集合的内部实现


SET的应用场景:

  1. 保存用户的标签(“用户画像”,根据用户历史兴趣行为投其所好)
  2. 利用Set来计算用户的共同好友,并可以进行好友推荐(SET集合求交集相对比较容易)
  1. 使用Set进行UV(去重),UV指的是每个用户的访问量(访问不同页面的个数),PV是整体用户的浏览量

zset数据类型

ZSET:有序集合,存储的元素唯一且有序(升序或者降序)

使用

ZADD:向zset添加一组或多组元素和分数 分数可以被表示为小数,要求member是唯一的,分数可以相同,首先是按照分数进行排序,如果分数相同再按照元素的字典序排列


语法格式:ZADD key [NX | XX][GT|LT] [CH] [INCR] score member [score member …]  (score和member可以相互查找)


LT:新的分数比之前的分数小就会更新


GT:新的分数比之前的分数大就会更新


CH:该参数会使返回值包含修改成功的元素个数


INCR:对于指定的元素加上指定的分数,但只能指定一个元素和分数,并且返回值变成修改后的分数值


时间复杂度:O(log N)  N是集合元素的个数,由于ZSET是有序的结构,要求新增的元素要放到合适的位置


返回值:返回新增成功的元素个数,对元素修改后会重新进行排序


ZCRAD:获取一个zset的基数,即zset中的元素个数


语法格式:ZCARD key


时间复杂度:O(1)


返回值: zset中的元素个数


ZCOUNT: 返回分数在min和max之间的元素个数,在默认情况下是闭区间,可以通过(进行排除边界值


语法格式: ZCOUNT key min max (min和max支持浮点数,并且支持inf(无穷大)和 -inf(负无穷大))


时间复杂度:O(log N) zset内部会记录每个元素当前的次序,zcount命令使用时先找到min和max对应的元素(log N),然后根据次序求个数


返回值:满足条件的元素列表的个数


ZRANGE:查询有序集合中的元素详情


语法格式:ZRANGE key start stop [withscores]  withscores可以使返回结果加上分数


时间复杂度:O(log N + M) log N是根据下标找位置,M是对start和stop之间进行遍历


返回值:区间内的元素列表


ZREVRANGE: 返回指定区间里的元素,分数按照降序排序


语法格式:ZRANGE key start stop [withscores]  withscores可以使返回结果加上分数


时间复杂度:O(log N + M) log N是根据下标找位置,M是对start和stop之间进行遍历


返回值:区间内的元素列表


ZRANGEBYSCORE: 返回分数在min和max之间的元素


语法格式:ZRANGE key max min [withscores]  withscores可以使返回结果加上分数


时间复杂度:O(log N + M) log N是根据下标找位置,M是对start和stop之间进行遍历


返回值:区间内的元素列表


ZPOPMAX:删除并返回分数最高的count的个数(相当于尾删)


语法格式:ZPOPMAX KEY [COUNT]


时间复杂度:O(log N * M)  N是有序集合的元素个数,M是要删除的元素个数 (查找到特定位置再进行删除)


返回值: 分数和元素列表


BZPOPMAX:ZPOPMAX的阻塞版本


语法格式:BZPOPMAX key [key …] timeout


时间复杂度:O(log N) 删除最大值花费的时间


返回值:元素列表


ZPOPMIN:删除并返回分数最低的count个元素


语法格式:ZPOPMIN key [count]


时间复杂度:O(logN * M)


返回值:分数和元素列表


BZPOPMIN:ZPOPMIN的阻塞版本


语法格式:BZPOPMIN key [key …] timeout


时间复杂度:O(log N) 删除最大值花费的时间


返回值:元素列表


ZRANK:返回指定元素的排名,升序


语法格式:ZRANK key member


时间复杂度:O(log N) 查询位置


返回值:排名(即元素的下标,)


ZREVRANK:返回指定元素的排名,降序


语法格式:ZREVRANK key member


时间复杂度:O(log N) 查询位置


返回值:排名(即元素的下标)


ZSCORE:返回指定元素的分数


语法格式:ZSCORE key member


时间复杂度:O(1)


返回值:分数


ZREM:删除指定的元素


语法格式:ZREM key member [member …]


时间复杂度:O(M * logN)


返回值:删除成功的元素个数


ZREMRANGEBYRANK: 删除指定范围的元素(按照排序)


语法格式:ZRENRANGEBYRANK key start stop


时间复杂度:O(logN + M) M指的是区间内的元素个数,N指的是集合内的元素个数


返回值:删除成功的元素个数


ZREMRANGEBYSCORE: 按照分数删除指定范围的元素


语法格式:ZREMRANGEBYSCORE key min max


时间复杂度:O(logN + M)


返回值:删除成功的元素个数


ZINCYBY:为指定的元素关联的分数添加指定的分数值 ,操作后集合会保持有序


语法格式:ZINCRBY key increment member


时间复杂度:O(log N)


返回值:增加后的元素的分数


ZINTESTORE:将交集结果保存到另一个destination中


语法格式:ZINTERSTORE destination numbers key [key …] [WEIGHTS weight][weight …] [AGGREAGATE <SUM | MIN |MAX>]


Numbers: 描述后面有几个key参与运算,避免选项和keys混淆


Weights:权重,此处的权重相当于一个系数,会乘以当前的分数


Aggregate:当member相同score不同时,分数的计算规则<SUM | MIN |MAX>,默认规则时SUM(加和)


时间复杂度:O(M*log M)


返回值:destination中的元素个数


ZUNIONSTORE:将并集结果保存到另一个destination中


语法格式:ZUNIONSTORE destination numbers key [key …] [WEIGHTS weight][weight …] [AGGREAGATE <SUM | MIN |MAX>


时间复杂度:O(M*log M) + O(N)


返回值:destination中的元素个数


Zset的内部编码方式:如果有序集合内部的元素个数较少或者单个元素体积较小时使用ziplist进行存储,如果当前元素个数较多或者单个元素体积较大时使用skiplist进行存储


应用场景:


排行榜系统(热搜榜、游戏天梯排行)(关键要点:排行“分数”是实时变化的,能够高效实现更新排行)

其他数据类型

Stream数据类型:是一个阻塞队列,作为消息队列的一个重要支撑,属于是List中的blpop和brpop的升级版本

Geospatial数据类型:用来存储坐标(经纬度),存储一些点之后就可以让用户给定一个坐标,去从刚才存储的点进行查找(按照半径或矩形区域等),常用于地图中


HyperLogLog数据类型:估算集合中的元素个数


Bitmap(位图)数据类型:位运算


Bitfields(位域)数据类型:可以简单理解为字节数组,然后把这个字节数组中的某几个位赋予特殊的含义,并可以进行读取、修改以及算数等运算,可以节省空间


渐进式遍历:每执行一次命令,只获取到其中一小部分,要想得到所有的key,就需要多次执行渐进式命令(“化整为零”),遍历过程中随时都可以终止,不会对服务器产生任何副作用


代表命令SCAN:


语法格式:SCAN cursor [MATCH pattern] [COUNT count] [TYPE type]


Cursor: 光标指向当前遍历的位置,从0开始但是并不代表下标


Match:匹配模式


Count:限制一次命令匹配得到的元素个数,只是一个“提示\建议”,并不是精确的数值,不用每次设置成相同的数字


Type:指定遍历value的类型


数据库管理命令:Redis中的数据库是现成的,作为用户不能创建新的数据库,也不能删除已有的数据库。


默认Redis提供了16个数据库(0~15),这16个数据库中的数据是隔离的,默认使用的数据库是0号


Select index (index指的是数据库编号):切换数据库


Dbsize:获取到当前数据库中key的个数


Flushdb:删除当前数据库中所有的key


Flushall:删除所有数据库中所有的key

四、maven项目中使用Redis

在maven项目中使用的是Jedis来操作redis

首先从maven中央仓库中引入jedis依赖

<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>4.4.3</version>
        </dependency>

在连接云服务器时实现本地端口的SSH端口映射,提高本地访问Redis的安全性;

使用代码来操作Redis:

Redis的各种命令都可以通过Jedis的方法来实现:jedis官方文档

五、SpringBoot项目中使用Redis

在创建SpringBoot项目在NoSQL中勾选redis依赖:

在配置文件中添加redis的地址和端口号:

spring:
  redis:
    host: 127.0.0.1
    port: xxxx

在Spring中使用RedisTemplate来操作Redis,相比jedis不能直接操作,而是需要选择相应的数据类型再进行操作:

例如操作字符串类型:

    @Autowired
    private RedisTemplate redisTemplate;
    @Test
    void testString() {
        // 设置数据
        redisTemplate.opsForValue().set("key1","张三");
        redisTemplate.opsForValue().set("key2","lucy");
        // 测试数据
        Assertions.assertEquals("张三",redisTemplate.opsForValue().get("key1"));
        Assertions.assertEquals("lucy",redisTemplate.opsForValue().get("key2"));
    }

想要执行Redis的一些原生命令,就需要使用RedisTemplate中的execute方法,使用lamda表达式来实现,以flushall命令为例:

        // 清空数据库
        redisTemplate.execute((RedisConnection connection) ->{
            connection.flushAll();
            return null;
        });

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
2月前
|
存储 缓存 NoSQL
介绍一下Redis
【10月更文挑战第19天】介绍一下Redis
|
2月前
|
存储 缓存 NoSQL
Redis系列
Redis系列
|
7月前
|
监控 NoSQL 算法
Redis为什么这么快
Redis为什么这么快
42 4
|
6月前
|
缓存 NoSQL 关系型数据库
记一次redis使用问题
记一次redis使用问题
30 0
|
NoSQL API Redis
Redis
Redis 是一个开源的、支持网络、可基于内存亦可持久化的日志型、key-value 数据库,它支持多种数据类型,如字符串(string)、哈希(hash)、列表(list)、集合(set)和有序集合(sorted set)等。Redis 提供了多种语言的 API,通常被称为数据结构服务器。
181 1
|
存储 缓存 NoSQL
Redis为什么那么快
Redis为什么那么快
119 1
Redis为什么那么快
|
消息中间件 存储 负载均衡
|
运维 NoSQL Shell
redis-2
redis-2
80 0
|
NoSQL Java Redis
Redis4
Redis4
44 0
|
存储 缓存 NoSQL
Redis初探
本篇深入介绍了Redis(Remote Dictionary Server)这一开源的内存数据存储系统,以及它在现代应用开发中的用途和优势。首先,我们对Redis进行了初步探索,解释了Redis是什么,它的主要特点以及适用场景。接着,我们详细讨论了Redis的安装和配置过程,提供了在Linux环境下安装Redis的步骤,并展示了如何启动和关闭Redis服务器。
227 0