Redis学习笔记(一) [初识Redis,学习常用的5种数据类型]

近期计划对redis再进行一段详细的学习,
在B站找到了尚硅谷的redis教学视频->【尚硅谷】Redis 6 入门到精通 超详细 教程,进行学习记录



🛴1.关于NoSql的概念引入


首先从技术的发展来看,大致可以分为三点:
(1) 功能性的方面:Java语言,JSP页面,Tomcat服务器,H5前端语言,Linux操作系统,JDBC数据库连接驱动,SVN版本控制;
(2) 扩展性的方面:比如学过的这些框架,都具有很好的扩展性->,Spring,SpringMVC,Hibernate,Mybatis;
(3) 性能方面: 比如这个NOSQL数据库,Java线程,大数据相关的Hadoop,Nginx反向代理服务器,MQ消息队列,ElasticSearch搜索引擎

Web1.0时代的数据服务

在这里插入图片描述

这样的单体架构是没有太大压力的,随着Web2.0时代来临,用户的访问量大幅度提升,同时产生大量用户数据,互联网数据产生的大量数据,造成访问量压力.

在这里插入图片描述

首先是这个CPU的内存压力问题;

比如说,现在使用了Nginx反向代理服务器,后端开了两个服务,此时用户在服务器A登录了,产生了session会话,那么要是切换到服务器B,怎么无缝切换呢?

  • 1.首先可以考虑使用浏览器cookie存储,但是安全性不能保证;
  • 2.可以考虑使用session复制,但是一直复制的话,会产生数据冗余问题;
  • 3.那么采用NOSQL数据库,比如redis进行缓存,将第一次登录产生的session会话存储起来,其他服务需要时,在redis缓存中获取即可.

在这里插入图片描述

IO的压力问题

在这里插入图片描述


🌈1.1 NoSql概念

那么初步了解一下什么是NoSql吧!
NoSql也就是非关系型数据库,不依赖于业务逻辑进行存储,采用了key-value键值对的形式进行存储;
它的几个特点:(1)不支持ACID原则,(2)在性能方面优于SQL,(2)不遵循传统SQL的标准;

常用的场景:高并发的海量数据使用,

不适用的场景:

  • 基于SQL的结构化查询存储场景,
  • 处理复杂的关系,[就需要考虑使用即使查询]; -
  • 需要事务支持的;

可以看看常见的NoSql数据库:

Mecache :

  • 数据在内存中,一般不进行持久化;
  • 支持简单的key-value键值格式,支持类型单一化;
  • 作为缓存数据库来辅助持久化的数据库(比如MYSQL).

Redis

  • 数据在内存中,可支持持久化,主要用于数据的备份恢复;
  • 不但支持基础的键值对格式,还支持其他类型 (list,set,hash,zset);
  • 也是作为辅助性质的缓存数据库使用;

MongoDb

  • 特点:高性能,开源且模式自由的文档型数据库
  • 数据都位于内存中,若内存不足,就会把不常用的数据存入硬盘,
  • 虽采用键值对格式,但对于value提供查询功能(比如JSON这样的);
  • 可根据数据的特点替代RDBMS(关系数据库管理系统),作为独立的数据库;
  • 可以配合RDBMS,存储特定的数据.

🌈1.2行式数据库 | 列式数据库

行式数据库可以这么理解,比如这个数据表存储的这三条信息,在行式数据库的规则中,就会采用一行一行的进行存储;

  • 比如需要查询id为3的数据,那么效率就很快;
  • 若查询年龄的平均数时,查询时就会慢一点;

在这里插入图片描述

列式存储数据库

在这里插入图片描述


🛴2.Redis概述与安装使用


🌈2.1基础知识

  • 使用 C 语言开发的数据库,基于内存存储,具有过期失效策略;
  • 支持value类型存储,可使用的数据类型有 String[字符串],List[链表],set[集合],zset[有序集合],hash[哈希];这些数据类型还支持push/pop,add/remove的原子性操作;
  • 支持数据的持久化,可以将内存中数据存入硬盘,重启时加载使用;具有完好的容灾恢复机制;
  • redis采用了单线程的多路IO复用;
  • redis还可支持主从读写分离的同步机制.

🌈2.2安装使用

安装部分; 之前已经安装过redis—>

在这里插入图片描述

(1)前台启动

前台启动的方式; [不推荐使用]
输入 ./redis-server
这个弊端就是一旦这样启动redis后,我们不能在这个页面执行操作其他的命令;
使用ctrl+c即可停止服务;在这里插入图片描述


(2)后台启动

后台服务启动的方式;进行配置;
这里可以将redis的配置文件拷贝一份放置到etc目录下;
(这里之前由于上次进行主从练习,所以将配置文件做了三份);
在这里插入图片描述
此时 cd /etc键入该目录;ls查看文件;
在这里插入图片描述

deamonize no 改为deanonize yes;
可直接在ftp中使用记事本修改;在这里插入图片描述
或使用vi编辑器命令进行修改;
vi redis79.conf

在这里插入图片描述

然后回到之前安装redis的目录;
注意启动的是etc下完成配置的文件;
在这里插入图片描述

此时即成功启动;
可使用命令查看

ps -ef | grep redis

在这里插入图片描述

使用这种方式的话,可以采用客户端来连接redis

先输入命令

./redis-cli

在这里插入图片描述

可输入命令 ping查看;
若需要退出,可使用shutdown 命令退出
或者输入exit 退出后,在查看进程时,采用kill -9停止对应的进程号即可;


🌈2.3相关的知识说明

  • 默认是6379端口号;

  • 这个redis它默认采用16个数据库,类似于数组从零开始的索引下标;初始启动时默认使用0号数据库;

  • 使用命令 select <dbid>可以切换数据库;
    比如切换到6号库
    在这里插入图片描述

  • 可以统一进行密码管理,所有数据库此案有同样的密码;

  • 可使用命令dbsize 查看当前数据库的key键的数量;

  • 命令flushdb可清空当前数据库,

  • 命令flushall 可通杀全部的数据库;

Redis采用了单线程 + 多路IO复用技术;

  • 这里的多路复用是指使用一个线程检查多个文件描述符(socket)就绪状态,例如调用select 或 poll函数方法;传入多个文件描述符,若有一个文件描述符就绪,则进行返回,否则可以阻塞直到超时,得到就绪状态后会进行真正的操作可支持在同一个线程中执行,或者启用线程池执行;
  • 多线程+锁(缓存的memcached)
  • 单线程+多路IO复用(redis);
  • 和memcache不同之处: redis支持多种数据类型,支持持久化, 采用了单线程+多路IO复用;

这里的单线程+多路IO复用,可以这样理解;
比如这个买票的案例,黄牛在火车站买票即可看作是单线程的处理;
而其他的乘客在向黄牛发出买票的请求后,可看做多路的IO操作,用户在等待黄牛的票据时,可以去做自己的事情,不需要在这里进行一直阻塞等待;
在这里插入图片描述


🛴3.key键操作 以及常见的几种数据类型


🌈3.1key键的操作


📢3.1.1基本概念及常用命令


  • keys * 命令可查看当前数据库中的所有key;当然可以匹配数据库使用 keys * 指定的数据库
  • exists key 可以判断某个key是否存在;
  • type key 可查看key的类型
  • del key 可删除指定的key数据
  • unlink key 可根据指定的value选择非阻塞式的删除; (注意只是将keyskeyspace元数据中删除,真正的删除会在后序的异步操作指向);
  • expire key 秒数 可为指定的key设置过期时间;
  • ttl key 可查看当前key还有多少秒过期, (-1 表示永远都不失效,-2表示已经失效);
  • select 命令可用于切换数据库;
  • dbsize 可查看当前数据库的key数量

📢3.1.2练习操作


练习;
由于这个初始化,里面没有数据;先设置几个key进去
在redis启动后,使用 set 键名 value值命令即可
在这里插入图片描述

  • 试试命令keys *;可看到设置的几个键;
    在这里插入图片描述
  • 使用命令 exists key 可查看是否存在;
    返回(0)代表不存在该key;

在这里插入图片描述

  • 可使用type 键名 查看键的类型;
    在这里插入图片描述

  • 使用命令del key名删除k2,查看效果;
    在这里插入图片描述

  • 尝试对k3使用expire 键名 过期时间设置一个过期时间50秒; 然后使用ttl key名 查看是否过期;
    在这里插入图片描述

  • 对于这个仅保留下来的键k1;有没有设置过期时间,那么它就是一直有效的;ttl key名若返回-1 则说明永不失效;
    在这里插入图片描述


🌈3.2 数据类型(1)String—字符串


📢3.2.1基本概念及常用命令


  • String字符串作为最基本的类型,一个key对应一个value;
  • String类型是二进制安全的,也就是说Redis的String可以包含存入任何数据,比如说 jpg/png类型的图片(或者是序列化的对象)都可以;
  • String类型作为redis最基本的数据类型,一个redis中的字符串value可以最多存 512M;

String的数据结构是可变的简单动态字符串,内部实现类似于ArrayList结构,采用了预分配冗余空间的方式减少内存的频繁分配操作.
在这里插入图片描述

内部采用当前字符串实际分配的空间, 容量capacity 一般高于(len)实际字符串的长度;

  • 当字符串的长度小于1M时,扩容都会加倍现有的空间;
  • 若长度超过1M,扩容时,仅扩容1M空间;
  • 注意字符串最大长度512M.

常用的命令学习

  • set key value 添加键值对的命令;
  • *NX 当数据库中的key不存在时,可以将 key-value添加到数据库;
  • *XX 当数据库汇总的key存在时,可以将key-value添加到数据库,与NX参数互斥;
  • *EX key的超时秒数;
  • *PX key的超时毫秒数,与EX参数互斥;

  • get key 查询对应的键值;
  • append key value 将给定的value 值追加到原来值的末尾位置;然后返回总的长度值;
  • strlen key 获取到指定key值的长度;
  • setnx key value只要在key不存在时,可设置key的值;(即这个 key要是存在,将无法对这个key的value值进行覆盖)

  • incr key

    • 可将key中存储的数字值增加1;
    • 只能对数字值进行操作,如果该数字为空,那么新增值为1;
  • decr key

    • 可将key中存储的数字值减少1;
    • 只能对数字值进行操作,如果该数字为空,那么新增值为-1;

  • incrby /decrby key 步长 可将key中处处的数字值进行增或减操作,自定义步长;
    • 注意原子性问题 incr key 时间复杂度为O(1);
    • 对于存储在指定key的值进行原子性的+1操作;
    • 这里原子性操作是指不会被线程调度机制打断的操作; 该操作开始后,就会一直运行到结束,其中不会有任何的context switch(切换线程出现).

关于原子性的问题分析
学习JMM时,知道了在Java中的i++ 就不是原子性操作;
比如说现在内存中的一个共享变量值为 i=0; 那么使用线程A和线程B分别对这个变量i 进行++100的操作,最终值的范围 可能为 2 ~ 200

因为线程A和线程B在执行过程中,可能会被对方打断操作;


  • mset key1 value1 key2 value2 ..... 可以同时设置一个/多个键值对;
  • mget key key2 key3 可以同时获取一个或者多个键值对;
  • msetnx key1 value1 key2 value2..... 同时设置一个或者多个 键值对时,当且仅当所有给定的key都不存在;(注意若有一个失败,则全部失败);

  • getrange key 起始位置 结束位置 可获取值指定范围的值,类似于Java语言中的substring函数;这个范围是左右封闭的区间;
  • setrange key 起始位置 新的value 从起始位置开始 可用新的value 覆盖 指定的key存储的字符串值;

  • setex key 过期时间 value 可在设置键值的同时,设置单位秒数的过期时间;
  • getset key value 以新换旧,采用设置的新value替换指定key的值, 且返回原来的value值

📢3.2.2练习操作


练习:
(1)首先将刚才操作创建的结果key键删除,在进行接下来的学习操作

使用命令flushdb清空数据库,可看到当前库中已无数据;
在这里插入图片描述

(2)设置存入两个新的键值;

k1 - xiaozhi001
k2 - xiaozhi002
在这里插入图片描述

(3)使用get key 命令,获取到指定的键的值;
在这里插入图片描述
然后使用set k1 新值 命令,操作k1,会发现新值将原来的值直接覆盖;
在这里插入图片描述
(4)使用append key value 将给定的value 值追加到原来k1值的末尾位置;返回一个长度;
在这里插入图片描述
(5)命令strlen key可返回指定键的长度;

在这里插入图片描述

(6)命令setnx key value只要在key不存在时,才可以设置key的值;
来试试对k1操作;(可发现这里由于k1存在,设置的值无法生效);

在这里插入图片描述
为了接下来的练习操作,再添加几个新的键值对 ;
在这里插入图片描述
(7) 试试 incr key命令,对数字值进行加一操作;

在这里插入图片描述
(8) 试试 decr key 命令,对于数字值进行减1操作;
在这里插入图片描述
(9) 尝试使用命令incrby key 步长值 进行新增指定步长操作 ;
使用命令decrby key 步长值 进行减少指定步长操作 ;

在这里插入图片描述

(10)使用 mset key1 value1 key2 value2 .....创建多个键值对学习;
可用mget命令获取多个键值对;

在这里插入图片描述
(11)使用msetnx key1 value1 key2 value3 .... 设置多个键值对时,若其中一个键已存在,则该命令设置的键值对都不会生效;

在这里插入图片描述

当设置的键值对都不存在时,才会添加成功;
在这里插入图片描述

(12) 命令getrange key 起始位置 结束位置 ;截取指定位置的值; 这个范围是左右封闭的区间;
在这里插入图片描述

(13)使用命令 setrange key 起始位置 新的value ;设置新值;
user的索引9开始,使用iscodersss替换接下来的10位字符,
原先的user值被彻底替换;
在这里插入图片描述

(14)练习使用setex key 过期时间 value 命令,设置键值对的同时,设置单位为秒数的过期时间;

在这里插入图片描述

(15) 练习使用getset key value 设置新的值替换旧值,

在这里插入图片描述


🌈3.3 数据类型(2)List—列表


📢3.3.1基本概念及常用命令


  • 单键多值的存储方式;
  • redis列表采用了简单的字符串列表,按照插入顺序进行排序,可添加一个元素到列表的头部/尾部;
  • 底层采用双向链表,处理两端的节点操作性能好,但是处理中间节点的数据时,性能差一点
    在这里插入图片描述

  • 实际上这个List类型的数据结构可以理解为快速链表quickList,
  • 首先在列表元素较少的情况下会使用一块连续的内存进行存储,该结构是ziplist,即压缩列表的形式;
  • 可以将所有的元素紧挨着一起存放,分配时采用连续的内存;
  • 当数据量较大时变为quicklist
    在这里插入图片描述

由于普通的链表需要附加的指针空间过大;
比如说这个列表存储的是int 类型的数据,结果上还需要使用额外的指针prev以及next指针;
在Redis中将链表和ziplist结合形成quicklist,即将多个ziplist使用双向的指针,连接串起来使用;


常用命令

  • lphsh/rpush key value1 value2 value3 .... 从左边/右边插入一个或者多个值,
  • lpop/rpop key 从左侧/右侧弹出一个值;
  • 值在则键在, 值光则键亡
  • rpoplpush key1 key2 从key1 列表的右边弹出一个值,插入到key2列表的左边;
  • lrange key start stop 按照索引下标获得元素,(由左至右).

  • lrange 指定列表名 0 -1 0:左边第一个, -1 右边第一个; (0-1表示获取所有)
  • lindex key index 按照索引获取元素,(注意是从左至右的);
  • llen key 获取列表长度;

  • linsert key before value newvalue 在value的后面添加一个newvalue值;
  • lrem key n value 从左边删除指定的 n 个值(由左至右);
  • lset key index value 将列表key下标为index的值替换为指定的value;

📢3.3.2 练习操作


首先使用命令 flushdb清空数据库之前的数据;
(1) 使用lphsh k1 v1 v2 .... 创建列表,依次从左边为链表插入值;
命令lrange 起始位置 结束位置 可从左至右按索引获取元素

在这里插入图片描述
在这里插入图片描述

(2) 使用rphsh k1 v1 v2 .... 创建列表,依次从右边为链表插入值;
命令lrange 起始位置 结束位置 可从左至右按索引获取元素
在这里插入图片描述

在这里插入图片描述
(3) 使用命令 lpop key,从列表左侧弹出一个值;

在这里插入图片描述
(4)使用命令 rpop key,从列表右侧弹出一个值;
在这里插入图片描述

(5)使用命令rpoplpush key1 key2 从K1列表的右侧弹出一个值,添加到K2列表的左侧;
在这里插入图片描述

在这里插入图片描述

(6)使用llen 指定列表 命令获取到指定列表的长度;
使用lindex 指定列表 指定索引 获取到指定类别的指定索引位置的元素
;
在这里插入图片描述

(7)使用linsert 指定列表 before 指定元素 新元素 命令;
在指定的列表的指定元素之前,添加新的元素值

在这里插入图片描述
(8)可使用命令lrem 指定列表 指定个数 指定元素;
从左侧开始,在指定列表中的删除指定个数的指定元素;
在这里插入图片描述

(9)lset 指定列表 指定索引 新的元素值命令;
可将指定列表指定索引位置元素替换为指定的新元素值;
在这里插入图片描述


🌈3.4 数据类型(3)Set—集合


📢3.4.1基本概念及常用命令


  • 这个Set类型的也就是类似于List集合类型的; 特点是 Set可以自动去重处理;
  • set提供了判断某数据成员是否位于set集合内的重要接口;
  • set类型作为string类型的无序集合,底层采用了value为null的hash表,那么添加,删除,查询操作的复杂度都平均是O(1)的;

  • Set数据结构采用了dict字典,而这个字典的结构采用了哈希表实现;
  • 在Java中的HashSet内部实现采用了HashMap,但所有的value都指示到了同一个对象.
  • Redis的set集合,内部同样地采用了hash结构,所有value指向到同一个内部值.

常用命令

  • sadd key value1 value2 ..... 可以将一个或者多个元素存入到集合key中,已存在的元素就会被忽略;
  • smembers key 可取出该集合的所有值;
  • sismember key value可判断集合key是否包含当前的 value值,若包含则返回1,若无则返回0;
  • scard key 返回该集合的元素个数;
  • srem key value1 value2.... 删除集合中的某个元素,
  • spop key 随机从该集合中弹出一个值;
  • srandmember key n 随机从指定集合中取出n个值, 注意不是删除;

  • smove 源集合 目标集合 value 将某个集合的值移动到另一个集合;
  • sinter key1 key2 返回两个集合的交集
  • sunion key1 key2 返回两个集合的并集;
  • sdiff key1 key2 返回两个集合的差集元素( 例如:即除了交集元素之外的元素);

📢3.4.2 练习操作


首先采用flushdb命令清空数据库,在进行接下来的操作练习;

(1)可使用命令sadd key 值 值 .... 创建指定的set类型集合,会忽略已经存在的数据,即去重;
使用命令smembers 指定键 可获取到指定集合的所有数据

在这里插入图片描述

(2)使用命令sismember 指定集合 指定值 判断该指定集合是否存在指定值;
若存在则返回1; 若不存在则返回0;
在这里插入图片描述

(3)使用命令scard 指定集合 即可返回指定集合的元素个数;
使用命令 srem 指定集合 指定元素 集合删除指定集合中的指定元素
在这里插入图片描述
(4)可使用命令spop 指定集合 随机从指定集合中删除一个元素;
可使用命令srandmember 指定集合 指定个数 可随机访问指定集合的指定个元素;

在这里插入图片描述

先清空数据库,接下来的几个练习操作需要使用到2个以上的集合;
在这里插入图片描述
创建3个新的集合
在这里插入图片描述

(5)可使用命令 smove source destination value 将某个集合的元素移动到另一个集合;

在这里插入图片描述

(6) 使用命令sinter key1 key2 可返回两个集合的交集;
在这里插入图片描述

(7)可使用命令sunion key1 key2 返回两个集合的并集;
在这里插入图片描述

(8)可使用命令 sdiff key1 key2 返回两个集合的差集元素( 例如:即除了交集元素之外的元素);

在这里插入图片描述


🌈3.5 数据类型(4)Hash—哈希


📢3.5.1基本概念及常用命令


  • Hash类型是一个键值对的集合;
  • 采用了String类型的field和value的映射哈希关系表;所有采用hash适合存储对象;
  • 对用的数据结构有两种:ziplist压缩列表和 hashtable哈希表;当 属性值 (field-value)的长度较短时,可使用ziplist结构,反之则在于hashtable结构.

案例分析

比如说使用用户Id作为查找的key,存储的value用户对象包含着姓名,年龄,生日等信息,那么可用普通的键值结果存储.

可试试这几种存储方式进行存储:
方法(1) 可将用户id作为键, 序列化之后的对象(或者是转为JSON格式的对象) 作为value值存储;

若存储序列化之后的对象,那么就需要先进行反序列化再修改数据,然后序列化后进行存储;
若存储JSON格式的对象,那么就需要解析之后再修改数据,在转为JSON格式进行存储;
在这里插入图片描述

方法(2)
可将用户id+姓名作为键,存储当前用户的姓名数据,
用户的id+年龄作为键,存储当前用户的年龄数据;
用户的id+生日作为键,存储当前用户的生日数据

但是这样存储的话会出现用户Id数据冗余问题;
在这里插入图片描述

方法(3)
可以采用用户Id作为键; 而将用户的数据和对应的数据信息采用hash数据类型存入到value中;

在这里插入图片描述


常用命令

  • hset key field value 为key集合中的 field键 赋值 value;
  • hget key1 field 由key1集合中的field获取到value值;
  • hmset key1 field1 value1 field2 value2..... 可以一次性地为集合key1中的多个field属性设置value值;
  • hexists key1 field 判断这个key集合是否存在指定的field;
  • hkeys key 获取到当前集合下的所有field属性;
  • hvals key 获取到当前集合下的所有value值;
  • hincrby key field increment 为哈希表的key中的 field属性值 进行指定步长的增量操作;
  • hsetnx key field value 当这个field不存在时,将field的值设为value;

📢3.5.2 练习操作


(1) 使用hset 键 属性 值命令创建,键名为user:180user:181的两个用户数据;分别存储id,name,age的信息;
在这里插入图片描述
实际就是这样一个结构:

在这里插入图片描述

(2)使用命令hget 指定集合key 指定属性获取到集合中的属性值;

在这里插入图片描述

(3)使用命令hmset key1 field1 value1 field2 value2..... 可以快速地创建一个集合;
在这里插入图片描述
在这里插入图片描述

(4)可用hexists key1 field 判断这个key集合中是否存在指定的field;

在这里插入图片描述

(5)hkeys key 获取到当前集合下的所有field属性;
hvals key 获取到当前集合下的所有value值;

在这里插入图片描述

(6) hincrby key field increment 为哈希表的key中的 指定属性值 进行 指定的增量操作;

在这里插入图片描述

(7)hsetnx key field value 当这个field不存在时,将field的值设为value;
在这里插入图片描述


🌈3.6 数据类型(5)Zset—有序集合


📢3.6.1基本概念及常用命令


  • 有序集合zset也是没有重复元素的字符串集合;但它还为每个成员关联了一个score分数属性,默认按照由小到大的方式进行排序;
  • 集合中的成员虽不能重复,但分数score可重复;
  • 由于zset存储元素时有序,在进行范围查找时效率很高;

常用命令

  • zadd key score1 value1 score2 value2 ..... 将一个/多个member元素和它的score值存入有序集合key;
  • zrange key start stop withscores 获取到指定集合的下标在 start->stop之间的元素;
  • zrangebyscore key minmax withscores limit offset count 在有序集合key中获取到 score分数位于min和max之间的元素; [由小到大排序]
  • zrevrangebyscore key maxmin withscores limit offset count在有序集合key中获取到 score分数位于min和max之间的元素; [由大到小排序]

  • zincrby key increment value 对集合的指定元素score增加一个指定的数值;
  • zrem key value 删除该集合下,指定value值的元素;
  • zcount key min max 统计当前集合的指定范围内元素个数;
  • zrank key value 获取到指定value值 在指定key集合中的排名, [排名由0开始].

📢3.6.2练习操作


(1)使用zadd key score1 value1 score2 value2 .....命令模拟存储多个数据;
使用zrange 指定集合 起始 结束 返回指定范围内的数据;

在这里插入图片描述
(2)zrangebyscore key minmax withscores limit offset count 指定范围的从小到大进行排序

在这里插入图片描述

(3)zrevrangebyscore key maxmin withscores limit offset count指定范围的从大到小进行排序
在这里插入图片描述

(4)可用命令 zincrby key 指定的增量 指定的元素 ; 将指定集合中的指定元素的score增加指定的增量;

在这里插入图片描述
(5)使用 zrem 指定集合 指定元素 删除指定集合中的指定value元素

在这里插入图片描述
(6)使用命令zcount 指定集合 起始值 结束值 统计score在指定范围内的数据量个数

在这里插入图片描述

(7)使用命令zrank 指定集合 指定value 即可获取到指定的value在zrank中的排名;

在这里插入图片描述


📢3.6.3 数据结构


ZSet有序集合,类似于Java中的map结构,可以为每个元素赋予一个分数属性(权重)score,另一方面来看,这个结构又类似于TreeSet,在其中的元素按照score进行排序,可以得到每个元素的名词,也可以通过score的范围获取到元素的列表.

底层采用的数据结构为hash和跳跃表;
(1) 首先哈希结构 将 value和 score的关系映射关联起来,保证了元素value的唯一性, 可采用value找到对应的score权重值;
(2)跳表结构的目的是为了对 元素value进行排序,可根据score的范围获取到元素的列表;

在效率方面,跳表结构堪比于红黑树.


模拟查找的案例;

(1)在链表结构中找到 节点元素51 ,需要一个一个地进行遍历查找到数据;

在这里插入图片描述

(2)在跳表结构中找到 节点元素51;步骤相对来说少一点;

首先在第2层找到节点1,要找的51大于1,那么就像向下一个节点21查询,
再向后找,发现22->指向空元素,那么,此时可以转移到第1层;
周到元素41,再向后找,此时注意到这个51元素位于41和61之间,那么再下移到第0层;
查找到元素51;

在这里插入图片描述


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小智RE0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值