Redis基础

发布时间:2024年01月17日

目录

一、Redis简介

Redis的特性?

Redis的应用场景?

Redis过期删除策略?

Redis的单线程模型

二、Redis的全局命令?

三、Redis常见数据类型?

String数据类型

List数据类型?

Hash数据类型?

set数据类型

mset数据类型?

其他数据类型?

四、maven项目中使用Redis?

五、SpringBoot项目中使用Redis


一、Redis简介

Redis是基于键值对形式的NoSQL数据库,在Redis数据库中其键的类型必须是String,但是其值可以是string(字符串)、hash(哈希)、list(列表)、set(集合)、zset(有序集合)、 Bitmaps(位图)、HyperLogLog、GEO(地理信息定位)等多种数据结构和算法组成,所以说Redis能满足多种应用场景,Redis会将所有的数据存放在内存中,还可以将内存中的数据利用快照和日志的形式保存到硬盘中,因此读写性能也较好,并且在发生断电或者机器故障时,内存数据不会丢失。除此之外,Redis还提供键过期、发布订阅、事务、流水线、Lua脚本等附加功能。

Redis的特性?

  1. 在内存中存储数据:Redis是通过表来组织存储数据的,属于“关系型数据库”,Redis是通过键值对来存储数据的,key必须是String,Value可以是String、List、Set等数据结构,Redis自身的Hash表是通过哈希表来组织的,属于“非关系型数据库”
  2. 可编程性:可以通过简单的交互式命令或者脚本的方式,批量执行一些操作
  3. 可拓展性:可以在Redis原有提供的API的基础上在进行拓展
  4. 持久性:Redis会把数据主要存储在内存上,硬盘作为辅助(内存的数据备份),如果Redis重启了,就会在重启时加载硬盘中的备份数据,使Redis的内存恢复到重启前的状态。
  5. 支持集群:Redis作为分布式系统的中间件,能存储的数据是有限的,支持集群就能引入多个主机,部署多个Redis节点,每个Redis能够存储一部分数据
  6. 高可用性:Redis自身支持“主从”结构的,从节点相当于对主节点的备份。

Redis的应用场景?

  1. 当作数据库使用:Redis是存储在内存中的,访问速度较快,性能较好,Redis中存储的是全量数据,数据不会随便丢失,但是需要更多的硬件资源

  2. 作为缓存使用:Mysql存储数据多,但访问速度较慢,热点数据存储在Redis中(二八原则),Redis存储部分数据,全量数据是存储在Mysql中的,Redis中即使数据丢失也能从Mysql中再进行加载恢复出来的

  3. 会话数据存储在Redis中:之前的session存储在应用服务器中的,现在将会话存储在Redis中时,不论负载均衡器将用户请求放到那个应用服务器,都能通过Redis拿到会话信息,并且在应用重启后session信息不会丢失。

  4. 消息队列(服务器):对于分布式系统中服务器之间可以使用生产者-消费者模型(可以解耦合和削峰填谷),Redis也是客户端-服务器程序(Mysql也是)

Redis过期删除策略?

Redis的过期删除策略是定期删除和惰性删除相结合

惰性删除:假设key已经到过期时间了,但是暂时还没有删除,如果后面访问到了这个key,redis服务器就会触发删除key的操作,同时再返回一个nil;

定期删除:每次会抽取一部分,进行验证过期时间,保证抽取检查的过程的速度足够快(Redis是单线程的程序,主要的任务是处理每个命令的任务,如果扫描过期key耗用的时间太多了,正式处理的请求命令就有可能阻塞)

Redis并没有采取定时器的方式来实现过期key的删除

Redis的单线程模型

Redis只用一个线程来处理所有的命令请求(避免了线程安全问题),但并不代表一个Redis服务器进程内部只有一个线程,只是多个线程在处理网络IO,Redis的核心业务逻辑都是短平快的,不太消耗CPU资源,故可以使用单线程模型。

单线程模型的弊端:操作命令占用时间长就会阻塞其他命令的执行

Redis虽然是单线程但是效率高的原因(参照物是数据库(mysql、Oracle、sql server等))

  1. Redis的操作是访问内存,数据库是访问硬盘
  2. Redis的核心业务比数据库的更简单(数据库对数据的增删改查都有复杂的业务支持,这样的功能会耗用更多的额外开销)
  3. Redis的单线程模型避免了一些不必要的线程进程开销,Redis的核心业务逻辑都是短平快的,不太消耗CPU资源,多个线程对于Redis的提升不大

处理网络IO的时候,使用了epoll这样的IO多路复用机制

二、Redis的全局命令?

  • 必须要先进入redis客户端才能操作Redis命令
  • Redis命令不区分大小写
  • Redis内部是按照二进制来存储数据的,要想把二进制字节换回汉字,就需要客户端来支持 redis-cli --raw

keys pattern:查询当前服务器上匹配的key,通过一些特殊符号(通配符)来匹配key,时间复杂度是O(n),执行keys *的时间会非常长,不建议使用

Pattern:包含特殊符号的字符串,为了描述符合要求的字符串

?匹配任意一个字符

* 匹配0个或任意字符

[] 匹配[]其中的任意一个

[^] 排除其中的字符,其余都能匹配

[a-b] 匹配从a到b范围内的字符,包含边界字符

exists key [key...]:判断key是否存在,返回key存在的个数(针对多个key),时间复杂度为O(1),Redis是按照哈希表的方式来存储的

del key [key...]:?删除key,返回删除key的个数,若不存在返回0,时间复杂度为O(1)

expire key seconds:给指定的key设置过期时间,超出指定值就会被自动删除,该命令适用于存在的key,设置成功返回1,失败返回0,时间复杂度为O(1),时间单位是秒(例如短信验证码、优惠券的有效期)

ttl key:查询key的过期时间,key没有设置过期时间返回-1,key不存在返回-2,时间复杂度为O(1)

Flushall:清空redis上的所有数据,相当于清库

三、Redis常见数据类型?

String数据类型

常见命令:

SET:将string 类型的value设置到key中。如果key之前存在,则覆盖,?论原来的数据类型是什么。之前关于此key的TTL也全部失效。

语法格式: SET key value [expiration EX seconds|PX milliseconds] [NX|XX]

时间复杂度:O(1)

选项:

SET命令?持多种选项来影响它的?为:

? EX seconds?使?秒作为单位设置key的过期时间。

? PX milliseconds?使?毫秒作为单位设置key的过期时间。

? NX?只在key不存在时才进?设置,即如果key之前已经存在,设置不执?(不存在才执行)。

? XX?只在key存在时才进?设置,即如果key之前不存在,设置不执?(存在才执行)。

GET获取key对应的value。如果key不存在,返回nil。如果value的数据类型不是string,会报错。

语法格式: GET key

时间复杂度:O(1)

返回值:key对应的value,或者nil当key不存在。

MSET:?次性设置多个key的值。

语法格式: MSET key value [key value ...]

时间复杂度:O(N)N是key数量

返回值:永远是OK

MGET:?次性获取多个key的值。如果对应的key不存在或者对应的数据类型不是string,返回nil。

语法格式:MGET key [key ...]

时间复杂度:O(N)N是key数量,命令中key的数量,可以近似认为是O(1)

返回值:对应value的列表

SETNX设置key-value但只允许在key之前不存在的情况下。

SETXX设置key-value但只允许在key之前存在的情况下。

SETEX设置过期时间

PSETEX设置过期时间,单位是毫秒

语法格式:SETNX key value

时间复杂度:O(1)

返回值:1表?设置成功。0表?没有设置。

APPEND:如果key已经存在并且是?个string,命令会将value追加到原有string的后边。如果key不存在,则效果等同于SET命令

语法格式:APPEND KEY value

时间复杂度:O(1)

返回值:追加完成后string的长度(字节)(utf8编码中一个汉字是3个字节)

GETRANGE:返回key对应的string的?串,由start和end确定(左闭右闭)。可以使?负数表?倒数。-1代表倒数第?个字符,-2代表倒数第?个,其他的与此类似。超过范围的偏移量会根据string的?度调整成正确的值。

语法格式:GETRANGE key start end

时间复杂度:O(n)

返回值:string的指定范围的子串

SETRANGE:覆盖字符串的?部分,从指定的偏移开始,如果key不存在,会将offset之前的内容填充为0X00

语法格式:SETRANGE key offset value

时间复杂度:O(n)

返回值:替换后string的长度

STRLEN:获取key对应的string的?度(单位是字节)。当key存放的类似不是string时,报错。

语法格式:STRLEN key

时间复杂度:O(1)

返回值:string的长度

字符串类型的编码方式:

Int:8个字节类型的长整型

Embstr:小于等于39个字节的字符串,存储小数也是按照压缩字符串类型

Raw:大于39个字节的字符串

String类型的应用场景:

  1. 缓存
  2. 计数
  3. 共享会话
  4. 手机验证码(过期删除)

计数命令

时间复杂度均是O(1)

INCR:将key对应的string表?的数字加?。如果key不存在,则视为key对应的value是0。如果key对应的string不是?个整型或者范围超过了64位有符号整型,则报错。

语法格式:INCR key

INCRBY将key对应的string表?的数字加上对应的值。如果key不存在,则视为key对应的value是0。如果key对应的string不是?个整型或者范围超过了64位有符号整型,则报错。

语法格式: INCRBY key decrement

DECR:将key对应的string表?的数字减?。如果key不存在,则视为key对应的value是0。如果key对应的string不是?个整型或者范围超过了64位有符号整型,则报错。

语法格式:DECR key

DECRBY:将key对应的string表?的数字减去对应的值。如果key不存在,则视为key对应的value是0。如果key对应的string不是?个整型或者范围超过了64位有符号整型,则报错。

语法格式:DECRBY key decrement

INCRBYFLOAT:将key对应的string表?的浮点数加上对应的值。如果对应的值是负数,则视为减去对应的值。如果key 不存在,则视为key对应的value是0。如果key对应的不是string,或者不是?个浮点数,则报错。允许采?科学计数法表示浮点数

语法格式:INCRVYFLAOT key increment

List数据类型?

List列表类型:用于存储多个有序的字符串,约定起始下标从左侧0开始,两侧都可以进行插入和删除(可以当作栈和队列来使用)

List列表类型的特点:

  • 列表中的元素是有序的(元素顺序调换和之前的List是不等价的)
  • 区分获取和删除的区别(获取并不会修改列表,但是删除会修改列表)
  • 允许元素重复

常见命令(使用如下命令时要求key对应的value是list,否则就会报错):

LPUSH:将一个或多个元素从左侧(头插)到list中

语法格式:LPUSH key element [element...]

时间复杂度:O(1)

返回值:插入后List的长度

RPUSH:将一个或多个元素从右侧(尾插)到list中

语法格式:RPUSH key element [element...]

时间复杂度:O(1)

返回值:插入后List的长度

LRANGE:获取从start到stop的所有元素,左闭右闭

语法格式:LRANGE key start stop

时间复杂度:O(1)

返回值:指定区间的元素

当区间下标非法时,Redis会尽可能取到给定区间的元素

LPOP:从List左侧取出元素(头删)

语法格式:LPOP key

时间复杂度:O(1)

返回值:取出的元素或者nil

RPOP:从List右侧取出元素(尾删)

语法格式:RPOP key count count参数的使用在redis 6.2以及之后的版本

时间复杂度:O(1)

返回值:取出的元素或者nil

LINDEX:获取从左数第index位置的元素

语法格式:LINDEX key index

时间复杂度:O(N) N指列表的长度 该命令需要遍历链表

返回值:取出的元素或者nil

LINSERT:在特定位置插入元素

语法格式:LINSERT key <BEFORE | AFTER> pivot element 是在基准元素第一次出现的位置进行插入

时间复杂度:O(N)

返回值:插入成功后List的长度

LLEN:获取List的长度

语法格式:LLEN key

时间复杂度:O(1)

返回值:List的长度

LREM:删除指定的元素

语法格式:LREM key count element????

count是要删除的个数 count>0 从左向右删除, count<0 从右往左删除, count=0删除所有的元素

element是指要删除的值

时间复杂度:O(N)

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

LTRIM:删除指定范围的元素

语法格式:LRIM key start stop 保留start和stop区间内的元素,将两边的元素进行删除

时间复杂度:O(N)

返回值:是否删除成功

LSET:根据下标修改元素

语法格式:LSET key index element

时间复杂度:O(N)

返回值:下标不合法时会报错,否则返回ok

阻塞版本的命令:

blpopbrpop是lpop和rpop的阻塞版本(阻塞队列,支持“队列为空”的情况,不考虑“队列为满”的情况)和对应的非阻塞版本的作用一致(当list中存在元素时),但仍存在如下区别:

如果list为空,blpop和brpop就会一直阻塞到队列不空为止,阻塞期间Redis依然可以执行别的命令,并且可以显示设置阻塞时间

blpop和brpop可以同时指定多个key,命令中如果设置了多个键,那么就会从左到右来进行遍历,一旦有键对应的链表可以弹出元素,命令就会立即返回

如果多个客户端同时执行一个键pop,则最先执行命令的客户端会得到弹出的元素

BLPOP:从List左侧取出元素(头删)

语法格式:BLPOP key [key …] timeout(单位是s)Redis6允许设置超时时间为小数形式

这些List中右任意一个非空,blpop就都能把这些元素获取到并立即返回

如果这些List都为空,此时就需要进行阻塞等待,等待其他客户端往这些list中插入元素

时间复杂度:O(1)

返回值:

列表非空情况:二元组形式,可以说明数据来源与那个key,以及取到的数据

空列

表情况:进行阻塞等待,得到数据后进行返回,并返回等待时间

list的内部编码:通过quickList进行内部实现,quick List是链表和压缩链表的结合,整体是通过链表实现,链表的每个节点是一个压缩链表,每个压缩列表都不会太大然后用压缩链表进行相连,整体的操作效率高,并且能够节省空间

list类型的应用场景:

  1. 作为类似数组的结构来存储数据(班级中存储学生列表)
  2. 作为消息队列使用(生产者-消费者模型)
  3. 对于一对多场景中进行列表分页
  4. Pipline(流水线)机制,减少网络交互的次数
  5. 选择列表类型时:同侧存取(lpush和lpop或者rpush和rpop)为栈,异侧存取(lpush和rpop或者rpush和lpop)为队列

Hash数据类型?

Hash哈希类型:Redis自身属于hash键值对建构,value的类型也可以是Hash表类型(“fileld -> value”),此处的value也可以当作数字进行处理

常见命令:

HSET:设置Hash中指定的字段(field)的值(value),此处的value只能是字符串类型

语法格式:HSET key field value [ field value ...]

时间复杂度:O(1)

返回值:设置成功的键值对的个数

HGET:获取hash中指定字段的值。

语法格式:HGET key field

时间复杂度:O(1)

返回值:字段对应的值或者nil

HEXISTS:判定hash中是否有指定的字段

语法格式: HEXISTS key field

时间复杂度:O(1)

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

HDEL:删除hash中的指定字段

语法格式:HDEL key field

时间复杂度:O(1)

返回值:本次操作成功删除的字段个数

HKEYS:获取hash中的所有字段

语法格式:HKEYS key

时间复杂度:O(N)(N指的是hash表的长度),该操作会根据key找到hash,然后会进行遍历

返回值:字段列表

HVALS:获取hash中所有的值

语法格式:HVALS key

时间复杂度:O(N)

返回值:值列表

HGETALL:获取hash中所有的字段以及对应的值

语法格式:HGETALL key

时间复杂度:O(N)

返回值:所有的字段以及对应的值

HMGET:获取hash中多个field

语法格式:HMGET key field [field...]

时间复杂度:O(N)

返回值: 指定多个字段对应的值(field和value的顺序匹配)

HLEN:获取hash中所有字段的个数

语法格式:HLEN key

时间复杂度:O(1)

返回值:字段个数

HSETNX:在字段不存在的情况下,设置hash中的字段和值

语法格式:HSETNX key field value

时间复杂度:O(1)

返回值:1表示设置成功,2表示设置失败

HINCRBY:将hash字段对应的值添加指定的值

语法格式:HINCRBY key field increment

时间复杂度:O(1)

返回值:该字段变化后的值

HINCRBYFLOAT:将hash字段对应的值添加指定的值(浮点数)

语法格式:HINCRBYFLOAT key field increment

时间复杂度:O(1)

返回值:该字段变化后的值

HASH类型的应用场景

  1. 缓存
  2. 作为关系型数据库使用

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集合求交集相对比较容易)
  3. 使用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进行存储

应用场景:

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

其他数据类型?

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;
        });
文章来源:https://blog.csdn.net/m0_62404808/article/details/135633715
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。