当前位置: 首页 > news >正文

Redis-结构化value对象的类型

文章目录

  • 一、Redis的结构化value对象类型的介绍
  • 二、Redis的这些结构化value对象类型的通用操作
    • 查看指定key的数据类型
    • 查看所有的key
    • 判断指定key是否存在
    • 为已存在的key进行重命名
    • 为指定key设置存活时间
      • pexpire与expire
    • 查看指定Key的存活时间
    • 为指定key设置成永久存活
  • 三、Redis中的结构化value对象类型之String类型及其操作
    • String型的value典型操作之针对数字类型
    • String型的value典型操作之针对字节串类型
    • 设置String类型的key同时设置过期时间
    • 同时设置多个String类型的数据
    • 同时查看多个String类型的数据
    • 查看String类型的数据的字符长度
    • 查看要修改的key的原的值(输出在终端)同时修改key的值
    • 将key的值递增
      • 将key的值+1
      • 将key的值+n
    • 将key的值递减
      • 将key的值-1
      • 将key的值-n
    • 将key的值的末尾追加内容
    • 查看String类型的数据(字符串)的指定某一位到某一位的部分
    • 修改String类型的数据(字符串)的指定某一位的值
  • 四、Redis中结构化value对象类型之Map类型及其操作
    • Hash数据结构介绍
    • map的主要操作
    • Redis Map(Hash)类型的实际应用例子
  • 五、Redis中结构化value对象类型之List类型及其操作(操作中有栈和队列的思想)
    • 针对单个key的元素的List类型的操作
    • List类型的复杂的操作(方便类似生产者消费者模式场景的实现)
    • *拓展:生产者消费者模式
      • 核心概念
      • 模式特点
      • 工作流程
      • 实现要点
      • 示例代码(Python)
    • `lpush`和`rpush`命令用于给一个List类型的对象添加数据
    • `rpop`和`rpush`命令用于给一个List类型的对象删除数据
    • `llen`命令用于查看一个List类型的对象有几个数据
    • `lpush`推进去的数据需用`rpop`弹出、`rpush`推入的需用`lpop`弹出
    • `lindex`用于查看一个List类型的对象的(从左往右数)的第一个成员的值(0表示第一个成员)
    • `lrange`命令用于查看一个List类型的对象的(从左往右数) 第几个成员到第几个成员的部分
    • `linsert`用于在一个List类型对象中(从左往右数)的指定成员名的前或后插入一个成员
    • `rpoplpush`复合命令,用于将一个List对象(从右边)弹出一个成员然后紧接着操作另一个List对象(在左边)推入这个成员进去
    • `lrem`命令用于(从左往右数)删除指定次数的成员(如果有重复名的成员的话,那么count>1如果不是那么只写1)
    • `ltrim`命令用于保留List对象的(从左往右数)第几个到第几个的成员
    • `lset`命令用于设置一个List对象的(从左往右数)第几个成员的值(0表示第一个成员)
    • Redis List类型的实际应用例子
  • 六、Redis结构化value对象类型之Set类型及其操作
    • set基本操作
    • Redis中的Set的实际应用场景
  • 七、Redis结构化value对象类型之Sorted-Set类型及其操作
    • Sorted-Sort的基本操作
      • `zadd`
      • `zrange`
      • `revrange`
      • `zrangebyscore`
      • `zrank`
      • `zrem`
      • `zincrby`
      • `zcard`
      • `zscore`
      • `zremrangebyrank`
      • `+inf`和`-inf`以及`limit`参数
    • Redis中的Sorted-Set的实际应用场景

一、Redis的结构化value对象类型的介绍

Redis常用的value包含5种类型:string、list、set、map、sorted-set

上面的value对象(数据类型的对象)在Redis内部的通用结构如下:

typedef struct redisObject{unsigned type:4;	//":4"表示占用4位unsigned encoding:4;unsigned lru:REDIS_LRU_BITS;int refcount;void *ptr;
} robj;
  • type:指这些结构化类型
  • encoding:指的是这些结构化类型在具体的实现(承载)方式,同一个类型可以有多种实现,例如String可以用int来承载,也可用用封装的char[]来承载,List可用ziplist或者链表来承载;
  • lru:表示本对象的空转时长,用于有限内存下长久不访问的对象的清理;
  • refcount:是应用技术用于对象的垃圾回收
  • prt指向的就是以enconding方式实现这个对象的实际承载者的地址,例如string对象对应的sds地址(sds是一种结构)

二、Redis的这些结构化value对象类型的通用操作

查看指定key的数据类型

#进入redis-cli后
type <指定key名>

在这里插入图片描述

查看所有的key

# 进入redis-cli后:
keys *

判断指定key是否存在

# 进入redis-cli后
exists <指定key名>

在这里插入图片描述

为已存在的key进行重命名

# 进入redis-cli后
rename <已存在的原key名> <新key名>

为指定key设置存活时间

#设置以秒为单位的存活时间
expire <指定key名> <存活时间(多少秒)>#设置以毫秒为单位的存活时间
pexpire <指定key名> <存活时间(多少毫秒)>

pexpire与expire

pexpire: pico(微小单位)expire

在Redis中,EXPIREPEXPIRE命令都用于设置键的过期时间,它们的主要区别在于过期时间的单位不同:

  1. EXPIRE命令

    • EXPIRE命令用于为指定的键设置一个过期时间(单位为秒)。
    • 语法:EXPIRE key seconds
    • 其中key是要设置过期时间的键,seconds是过期时间,以秒为单位。
    • 例如,EXPIRE mykey 60会将键mykey的过期时间设置为60秒。
  2. PEXPIRE命令

    • PEXPIRE命令用于为指定的键设置一个过期时间(单位为毫秒)。
    • 语法:PEXPIRE key milliseconds
    • 其中key是要设置过期时间的键,milliseconds是过期时间,以毫秒为单位。
    • 例如,PEXPIRE mykey 60000会将键mykey的过期时间设置为60秒(60000毫秒)。

区别

  • 时间单位EXPIRE使用秒作为单位,而PEXPIRE使用毫秒作为单位。这允许PEXPIRE设置更精确的过期时间,特别是当需要比秒更细粒度的控制时。
  • 适用场景:如果你需要以秒为单位设置过期时间,使用EXPIRE;如果需要以毫秒为单位设置过期时间,使用PEXPIRE

使用场景示例

  • 如果你有一个缓存需求,需要在3600秒后过期,可以使用EXPIRE mykey 3600
  • 如果你需要在3600秒加上500毫秒后过期,可以使用PEXPIRE mykey 3600500

在实际应用中,选择EXPIRE还是PEXPIRE取决于你的具体需求和过期时间的精度要求。

查看指定Key的存活时间

永久存活,则返回-1

ttl <指定key名>

”ttl“指的是:time to live

为指定key设置成永久存活

persist <指定key名>

在这里插入图片描述

三、Redis中的结构化value对象类型之String类型及其操作

Redis的结构化value对象类型中的string能表达3中指的类型:

  • 字节串
  • 整数
  • 浮点数


3中类型间根据具体场景由redis完成相互间的自动转型,并且根据需要选取底层的承载方式;
比如,下面的数字类型就可以自动转换成字节串类型,然后可以进行字节串类型的一些操作,然而字节串类型就不可轻易转换成数字类型进行数字类型的操作;

String型的value典型操作之针对数字类型

操作描述
incr将指定key内容+1
decr将指定key内容-1
incrby将指定key的内容增加给定的值
decrby将指定key的内容减少给定的值
incrbyfloat将指定key的内容减少给定的浮点值

String型的value典型操作之针对字节串类型

操作描述
append将指定字节串的内容添加到指定key对应的value后
getrange对字节串value做范围截取
setrange对指定字符串内容覆盖,指定key对应的value,从指定位置开始覆盖
strlen获取字节串value的长度
getbit对字节串value,获取指定偏移量上的bit
setbit将字节串value视为bit串并设置从给定起始位置起设置值
bitcount将字节串value视为bit串并统计1的数量
bitop对多个key的value值做位操作,如:XOR、OR、AND、NOT

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


字节串和字符串的区别:

在计算机编程中,“字节串”(byte string)和“字符串”(string)这两个术语通常用来描述不同类型的数据结构,它们的区别主要体现在数据类型、存储内容和使用场景上:

  1. 数据类型

    • 字符串(String):通常指的是由字符组成的序列,每个字符在计算机中通常占用固定数量的比特(比如UTF-8编码中,一个英文字符占用1个字节,而一个中文字符可能占用3个字节)。字符串在编程语言中是一个基本的数据类型,用于存储和处理文本数据。
    • 字节串(Byte String):是由字节(byte)组成的序列,每个字节可以是0到255之间的任意值。字节串不关心字节的编码或它们代表的字符,它们只是原始的二进制数据。
  2. 存储内容

    • 字符串:存储的是字符数据,每个字符都有特定的编码(如ASCII、UTF-8等)。
    • 字节串:存储的是原始的字节数据,不进行任何字符编码转换,可以包含任何二进制值。
  3. 使用场景

    • 字符串:用于存储和处理文本信息,如用户输入、文件内容等。
    • 字节串:用于处理二进制数据,如文件的原始内容、网络传输的数据包等。
  4. 处理方式

    • 字符串:编程语言提供了丰富的字符串处理函数,如字符串拼接、查找、替换等。
    • 字节串:处理方式更接近于数组或缓冲区,通常用于低级的数据操作,如内存拷贝、网络通信等。
  5. 编码与解码

    • 字符串:在不同编程语言中,字符串的编码方式可能不同,但通常都是以某种字符编码存储。
    • 字节串:不涉及编码问题,它们是原始的字节流。
  6. 性能

    • 字符串:因为涉及到字符编码,处理字符串可能比处理字节串更复杂,性能上可能稍逊一筹。
    • 字节串:由于直接操作字节,通常在性能上更优。

在不同的编程语言中,这两个概念的具体实现和表现可能有所不同,但基本的区别大致如上所述。


设置String类型的key同时设置过期时间

set <key1> <value> [ex 存活时长秒数] [px 存活时长毫秒数]

在这里插入图片描述

同时设置多个String类型的数据

mset : multi-set

mset <key1> <value> <key2> <value> <key3> <value> ...

在这里插入图片描述

同时查看多个String类型的数据

mset <key1>  <key2>  <key3> ...

在这里插入图片描述

查看String类型的数据的字符长度

strlen <key名>

在这里插入图片描述

查看要修改的key的原的值(输出在终端)同时修改key的值

getset <指定key> <新值>

只输出原key的值,同时改变原key的值
在这里插入图片描述

将key的值递增

将key的值+1

incr <指定key名>

将key的值+n

原key值是数字时

incrby <指定key名> <要增加的个数n>
# 以浮点单位的递增
incrbyfloat <指定key名> <要增加的数(如:+4.5)>

将key的值递减

将key的值-1

decr <指定key名>

将key的值-n

原key值是数字时

decrby <指定key名> <要减的个数n>
# 没有decrbyfloat这样的命令

将key的值的末尾追加内容

set key1 xxxappend key1 666
# 那么key1的值就为:xxx666

查看String类型的数据(字符串)的指定某一位到某一位的部分

注意0表示字符串的第一位

set key1 lotus43xxx
getrange key1 0 4
getrange key1 5 6

在这里插入图片描述

修改String类型的数据(字符串)的指定某一位的值

setrange key1 6 q

在这里插入图片描述

四、Redis中结构化value对象类型之Map类型及其操作

  • Map型的value在Redis中又叫做Hash,它的最初实现是Hash表;一个Map可以包含若干个key-value,其中key不重复;
  • Redis本身就是key-value结构,它的value可以是map类型,此类型的value内部又是一个subkey-subvalue,map内部的key和value不能再嵌套map了,它只能是String型所能表达的内容:整型、浮点型、字节串

Hash数据结构介绍

Hash数据结构

  • 桶:bucket
  • Hash函数,取模3
  • 负载因子,扩容、缩容

map的主要操作

操作描述
hset设置哈希表中的单个或多个字段值。如果字段已存在,则会更新它的值;如果字段不存在,则会创建一个新的键值对。语法为hset key subkey_1 subvalue_1 [subkey_2 subvalue_2] ... [subkey_n subvlaue_n]
hmset设置哈希表中的多个字段值 但是 从Redis 4.0.0开始,HMSET被废弃,请使用HSET代替。
hget
hmget
hgetall
hkeys
hvals
hlen
hdel

由于map的value可以表示整数和浮点数,所以map也包含对特定的key的value做数字专有的操作,比如:

操作描述
hincrby可以原子地操作某个key对应的数字型value

以下是上面操作的例子:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

Redis Map(Hash)类型的实际应用例子

  1. 存储用户信息

    • 用户ID作为键,用户的属性(姓名、年龄、性别等)作为字段,避免将整个用户对象序列化成字符串。
  2. 配置项管理

    • 存储配置项,方便根据字段名快速访问和更新某个配置。
  3. 对象存储与缓存

    • 将数据原本存储在其他存储系统(如关系型数据库)中的数据缓存到Redis中,减少对原始数据源的访问压力并提高读取速度。例如,博客网站缓存文章的详细内容,使用HSETHGET命令存储和获取文章信息。
  4. 实时统计

    • 使用哈希来保存当前在线用户、页面浏览量和API请求次数等。例如,HINCRBY命令用于增加在线用户数或页面访问次数。

五、Redis中结构化value对象类型之List类型及其操作(操作中有栈和队列的思想)

List即列表对象,用于存储String序列

针对单个key的元素的List类型的操作

操作描述
rpush/lpush将指定的String内容添加到给定key对应的列表value的开头或末尾,例如:rpush key1 "a"操作将a这个字符串添加到列表尾,作为最后一个元素
rpop/lpop取出给定key对应的列表value的开头或末尾元素并删除之
lindex取出给定key对应的列表value的某个元素
lrange取出给定key对应的列表value的某个范围内的元素,例如lrange key1 0 9取得key1对应的value的前10个元素
ltrim将给定key对应的列表value的某个范围内的元素剪下来(保留下来)
trim:去除,剪掉

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

常用于消息队列
lpush: 在队列左边推入
rpop:弹出队列右边的第一个

rpush: 在队列右边推入
lpop:弹出队列左边的第一个
在这里插入图片描述

List类型的复杂的操作(方便类似生产者消费者模式场景的实现)

操作描述
blpop/brpop例如brpop key1 key2 60 指的是如果60秒内,key1非空则从key1对应的列表value中pop最右元素,否则从key2中pop,如果60秒内两个key始终为空,则超时返回

在这里插入图片描述

*拓展:生产者消费者模式

生产者消费者模式(Producer-Consumer Pattern)是一种并发设计模式,用于协调生产者和消费者之间的工作,以确保生产者生产的数据能够被消费者及时处理,同时避免数据的重复处理或丢失。这种模式在多线程环境中非常常见,尤其是在涉及到数据共享和线程同步的场景中。

核心概念

  1. 生产者(Producer):负责生成数据的线程或进程。
  2. 消费者(Consumer):负责处理数据的线程或进程。
  3. 缓冲区(Buffer):一个临时存储数据的容器,生产者将数据放入缓冲区,消费者从缓冲区取出数据进行处理。

模式特点

  • 解耦生产者和消费者:生产者和消费者之间不需要直接通信,它们通过缓冲区进行数据交换,这有助于降低系统的耦合度。
  • 线程安全:在多线程环境中,需要确保缓冲区的线程安全,避免数据竞争和条件竞争。
  • 同步机制:通常需要使用同步机制(如锁、信号量、条件变量等)来控制对缓冲区的访问。

工作流程

  1. 生产者生产数据:生产者生成数据后,将其放入缓冲区。
  2. 缓冲区管理:缓冲区负责存储数据,并提供同步机制以确保数据的一致性。
  3. 消费者处理数据:消费者从缓冲区取出数据进行处理。
  4. 同步控制:当缓冲区满时,生产者可能需要等待;当缓冲区空时,消费者可能需要等待。

实现要点

  • 锁(Locks):用于保护共享资源(如缓冲区)的访问,防止多个线程同时访问。
  • 信号量(Semaphores):用于控制对共享资源的访问数量,可以用于控制缓冲区的容量。
  • 条件变量(Condition Variables):用于线程间的协调,当某个条件满足时通知等待的线程。

示例代码(Python)

import threading
import time
import queue# 定义一个缓冲区
buffer = queue.Queue(maxsize=10)# 生产者
def producer():for i in range(20):time.sleep(1)buffer.put(i)print(f"Produced {i}")# 消费者
def consumer():while True:item = buffer.get()print(f"Consumed {item}")buffer.task_done()time.sleep(2)# 创建线程
producer_thread = threading.Thread(target=producer)
consumer_thread = threading.Thread(target=consumer)# 启动线程
producer_thread.start()
consumer_thread.start()# 等待线程结束
producer_thread.join()
buffer.join()  # 等待所有数据被处理
consumer_thread.join()

在这个示例中,我们使用Python的queue.Queue来实现缓冲区,它内部已经实现了线程安全的锁和条件变量。生产者线程生成数据并放入缓冲区,消费者线程从缓冲区取出数据进行处理。通过buffer.join()确保所有数据都被处理完毕后再结束程序。

生产者消费者模式是并发编程中一个非常基础且重要的模式,它有助于提高程序的效率和响应性。

lpushrpush命令用于给一个List类型的对象添加数据

rpoprpush命令用于给一个List类型的对象删除数据

llen命令用于查看一个List类型的对象有几个数据

lpush推进去的数据需用rpop弹出、rpush推入的需用lpop弹出

lindex用于查看一个List类型的对象的(从左往右数)的第一个成员的值(0表示第一个成员)

lrange命令用于查看一个List类型的对象的(从左往右数) 第几个成员到第几个成员的部分

0表示第一个元素

# 查看一个List类型的对象的所有内容
lrange <List对象名> 0 -1

在这里插入图片描述

linsert用于在一个List类型对象中(从左往右数)的指定成员名的前或后插入一个成员

在这里插入图片描述

rpoplpush复合命令,用于将一个List对象(从右边)弹出一个成员然后紧接着操作另一个List对象(在左边)推入这个成员进去

在这里插入图片描述

lrem命令用于(从左往右数)删除指定次数的成员(如果有重复名的成员的话,那么count>1如果不是那么只写1)

lrem <List对象>
在这里插入图片描述

ltrim命令用于保留List对象的(从左往右数)第几个到第几个的成员

在这里插入图片描述

lset命令用于设置一个List对象的(从左往右数)第几个成员的值(0表示第一个成员)

lset <List对象>

在这里插入图片描述

Redis List类型的实际应用例子

  1. 消息队列

    • Redis的List类型可以通过LPUSHRPUSH(或者反过来,LPOPRPOP)实现队列的功能,因此可以用Redis的List类型实现简单的消息队列。例如,使用LPUSH将消息放入队列,使用RPOPBRPOP弹出消息。
  2. 排行榜

    • LRANGE命令可以分页查看队列中的数据,适合将每隔一段时间计算一次的排行榜存储在List类型中,例如京东每日的手机销量排行、学校每次月考学生的成绩排名等。
  3. 最新列表

    • LPUSH命令和LRANGE命令能实现最新列表的功能,每次通过LPUSH命令往列表里插入新的元素,然后通过LRANGE命令读取最新的元素列表,如朋友圈的点赞列表、评论列表。
  4. 任务队列

    • Redis的列表数据结构可以用来实现任务队列,将需要处理的任务存储到列表中,然后通过消费者从列表中获取任务并进行处理,实现任务的异步处理和调度。

六、Redis结构化value对象类型之Set类型及其操作

Set类似List,但它是一个无序集合,其中的元素不重复


集合与其他数据结构的主要区别在于它的元素是唯一的,并且没有固定的顺序。而数组、表、树和图都可以存储有序元素或具有特定关系的数据。数组和表通常用于存储和访问结构化数据,树和图用于表示层次和网络关系。每种数据结构都有其特定的应用场景和优势,选择合适的数据结构可以提高程序的效率和性能。


集合(Set)在编程中有着广泛的应用场景,以下是一些常见的例子:

  1. 去重

    • 在处理数据时,经常需要去除重复的元素,例如从数据库查询结果中去除重复的记录,或者在处理用户输入时去除重复的选项。
  2. 数学集合操作

    • 在需要进行数学上的集合操作,如交集、并集、差集时,集合提供了直接的支持。
  3. 快速查找

    • 当需要快速判断某个元素是否存在于一个数据集中时,集合可以提供快速的查找功能。
  4. 权限控制

    • 在权限管理系统中,集合可以用来存储用户的角色或权限,方便进行权限的添加、删除和检查。
  5. 缓存实现

    • 集合可以作为缓存数据结构的一部分,存储最近访问或频繁访问的数据项。
  6. 对象属性检查

    • 在面向对象编程中,集合可以用来存储对象的属性或特征,方便进行属性的管理和检查。
  7. 唯一性保证

    • 在需要确保数据项唯一性的场合,如生成唯一的ID或序列号,集合可以用来存储已经使用过的值。
  8. 数据分片和分区

    • 在大数据应用中,集合可以用来将数据分片或分区,以便于并行处理。
  9. 配置管理

    • 在配置管理系统中,集合可以用来存储配置项,方便进行配置的添加、删除和查询。
  10. 推荐系统

    • 在推荐系统中,集合可以用来存储用户的兴趣点或标签,以便于生成个性化推荐。
  11. 社交网络分析

    • 在社交网络分析中,集合可以用来存储用户的好友列表或社交圈。
  12. 游戏开发

    • 在游戏开发中,集合可以用来管理游戏中的实体,如敌人、道具或玩家。
  13. 并发编程

    • 在并发编程中,集合可以作为线程安全的数据结构,用于同步和锁的管理。
  14. 测试和模拟

    • 在测试和模拟中,集合可以用来存储测试用例或模拟对象的状态。
  15. 算法实现

    • 许多算法,如排序、搜索、图算法等,都需要使用集合来存储中间结果或作为算法的一部分。

集合因其高效的元素管理和独特的性质,在软件开发中扮演着重要的角色。不同的编程语言提供了不同的集合实现,如Python的set和JavaScript的Set对象,它们都提供了丰富的API来支持集合操作。


set基本操作

操作描述
sadd/srem/sismember分别实现向set中增加、删除元素,以及检查某元素是否在set里
scard/smembers/srandmember分别实现统计元素个数、列出所有元素、随机获取元素
sinter/sunion/sdiff分别实现多个set的交集、并集和差集
sinterstore/sunionstore/sdiffstore分别实现将多个set的交集、并集、差集的结果储存在另一个key中
smove将set1的元素放入set2中
spop将集合的元素随机弹出删除(删除一个或多个)

以下是上面这些操作的例子:

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

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

Redis中的Set的实际应用场景

Redis的Set(集合)是一种无序的、不重复的元素集合,它提供了丰富的操作命令,适用于多种实际应用场景。以下是一些Redis Set的典型应用:

  1. 去重

    • 在需要去除重复数据的场景中,如从日志中提取唯一的IP地址、从用户提交表单中提取唯一的邮箱地址等,可以使用Set的SADD命令添加元素,自动过滤掉重复项。
  2. 在线用户列表

    • 可以使用Set来存储当前在线的用户ID。每当用户登录时,使用SADD命令将用户ID添加到集合中;用户登出时,使用SREM命令将用户ID从集合中移除。
  3. 标签系统

    • 在内容管理系统中,可以使用Set来存储文章或产品的标签。每个标签都是集合中的一个元素,而每篇文章或产品可以对应一个包含其所有标签的集合。
  4. 好友关系

    • 可以使用两个Set来表示用户的好友关系。例如,用户A的好友列表是一个Set,用户B的好友列表是另一个Set。检查两个用户是否为好友,只需要检查两个Set是否有交集。
  5. 抽奖活动

    • 在抽奖活动中,可以将参与者的标识(如用户ID或手机号)存储在一个Set中。使用SRANDMEMBER命令随机选择中奖者,确保随机性和唯一性。
  6. 商品推荐

    • 在电商网站中,可以使用Set来存储用户感兴趣的商品ID集合。通过分析这些集合,可以发现用户的偏好,并进行个性化推荐。
  7. 分布式系统的唯一性问题

    • 在分布式系统中,Set可以用来确保任务的唯一性,例如,防止同一个任务被多个节点重复处理。
  8. 实时竞拍系统中的出价者列表

    • 在实时竞拍系统中,可以使用Set来存储对某个商品出价的用户ID,这样可以快速检查某个用户是否已经出价,以及快速获取当前所有出价者。
  9. 社交网络中的共同好友

    • 可以使用Set来找出两个用户之间的共同好友。对于用户A和用户B,分别存储他们的好友集合,然后使用SINTER命令求交集,得到共同好友列表。
  10. 库存管理

    • 在库存管理中,可以使用Set来跟踪不同仓库中的商品。通过SUNION命令,可以快速合并多个仓库的商品列表,进行库存盘点。
  11. 投票系统

    • 在投票系统中,可以使用Set来存储已投票的用户ID,以确保每个用户只能投一次票。

Redis Set的这些应用场景展示了它在处理唯一性集合数据时的灵活性和效率。通过利用Set的特性,可以简化代码逻辑,提高系统性能。

七、Redis结构化value对象类型之Sorted-Set类型及其操作

Sorted-Set是Redis特有的数据类型,也是集合,但它是一个有序的key-value对**:

  • key:在一个sorted-set中不重复
  • value:是一个浮点数,称为score;可以与其他key相同
  • 有序:sorted-set内部默认按照score从小到大排序

Sorted-Sort的基本操作

由于srted-set本省包含排序信息,在普通set的基础上,sroted-set新增了一系列和排序有关的操作:
Redis中的sorted-set(有序集合)是一种数据结构,它结合了集合(Set)的特性和可以对元素进行排序的能力。下面是Redis中sorted-set类型的具体操作和一些常用命令的详细说明:

zadd

  • 用途:向有序集合添加一个或多个成员,或者更新已存在成员的分数。
  • 语法ZADD key score1 member1 [score2 member2 ...]
  • 示例
    ZADD myzset 1 "one"
    ZADD myzset 2 "two"
    ZADD myzset 3 "three"
    
    这会将成员 “one”, “two”, 和 “three” 与对应的分数添加到名为 myzset 的有序集合中。如果成员已存在,则更新其分数。
    在这里插入图片描述

zrange

  • 用途:通过索引区间返回有序集合指定区间内的成员。
  • 语法ZRANGE key start stop [WITHSCORES]
  • 示例
    ZRANGE myzset 0 -1 WITHSCORES
    
    这会返回有序集合 myzset 中所有成员及其分数,按分数从小到大排序。
    在这里插入图片描述

revrange

  • 用途:返回有序集中指定区间内的成员,通过索引,分数从高到低。
  • 语法ZREVRANGE key start stop [WITHSCORES]
  • 示例
    ZREVRANGE myzset 0 -1 WITHSCORES
    
    这会返回有序集合 myzset 中所有成员及其分数,按分数从大到小排序。
    在这里插入图片描述

zrangebyscore

  • 用途:通过分数返回有序集合指定区间内的成员。
  • 语法ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
  • 示例
    ZRANGEBYSCORE myzset 0 5 WITHSCORES
    
    这会返回有序集合 myzset 中分数在0到5之间的所有成员及其分数。
    在这里插入图片描述

zrank

  • **用途:**确定某个key值在本sorted-set内按照顺序排在第几位(从0开始)
  • 语法:zrank sort--set类型对象 <key名>
    在这里插入图片描述

zrem

  • 用途:移除有序集合中的一个或多个成员。
  • 语法ZREM key member [member ...]
  • 示例
  ZREM myzset "one"

这会从有序集合 myzset 中移除成员 “one”。
在这里插入图片描述

zincrby

  • 用途:有序集合中对指定成员的分数加上增量。
  • 语法ZINCRBY key increment member
  • 示例
    ZINCRBY myzset 5 "two"
    
    这会将成员 “two” 的分数增加 5。
    在这里插入图片描述

zcard

  • 用途:获取有序集合的成员数。
  • 语法ZCARD key
  • 示例
    ZCARD myzset
    
    这会返回有序集合 myzset 中的成员数量。
    在这里插入图片描述

zscore

  • 用途:获取有序集合中指定成员的分数。
  • 语法ZSCORE key member
  • 示例
    ZSCORE myzset "two"
    
    这会返回成员 “two” 在有序集合 myzset 中的分数。
    在这里插入图片描述

zremrangebyrank

  • 用途:删除有序集合一定位置范围的一些元素
  • 语法zremrangebyrank <sorted-set对象> <开始位> <结束位>

在这里插入图片描述

+inf-inf以及limit参数

  • ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
    • key:指定有序集合的键名。
    • minmax:指定分数的最小值和最大值,可以是负无穷大-inf和正无穷大+inf,(inf:infinity)或者具体的数值。
    • [WITHSCORES]:可选参数,如果指定,命令会同时返回成员的分数。
    • [LIMIT offset count]:可选参数,用于限制返回结果的数量,offset指定开始返回的位置,count指定返回的数量。

在这里插入图片描述

Redis中的Sorted-Set的实际应用场景

Redis中的Sorted-Set(有序集合)是一种非常强大的数据结构,它在许多实际应用场景中都非常有用。以下是一些具体的应用场景:

  1. 排行榜系统

    • 游戏应用中的玩家排名、社交应用中的用户活跃度排名、电商应用中的商品销量排名等都可以使用Sorted-Set来实现。通过给每个用户或商品一个分数(比如分数、销量、活跃度等),可以很容易地根据分数对他们进行排序。使用ZADD命令添加或更新分数,ZREVRANGE命令获取前N名的用户。
  2. 延迟任务队列

    • Sorted-Set可以用于实现延迟任务队列。通过将任务的执行时间作为分数,任务的标识作为成员,将任务添加到Sorted-Set中。然后,可以通过ZRANGEBYSCORE命令查询到期的任务进行处理。
  3. 实时排行榜

    • 对于需要实时更新的排行榜,如股票价格排行、体育赛事得分排行等,Sorted-Set可以快速地添加新记录、更新现有记录,并能够通过分数区间查询来获取特定排名范围的数据。
  4. 多维度排序

    • 在一些场景下,可能需要根据多个维度对数据进行排序。例如,在一个应用商店中,除了根据下载量(分数)排序外,还可以根据最后更新时间进行次级排序。Sorted-Set可以通过组合这两个维度的值(例如,将下载量和更新时间戳连接起来)作为分数,从而实现多维度排序。
  5. 区间查询

    • Sorted-Set提供了ZRANGEZREVRANGE命令,可以按照排行榜中的排名范围进行查询,例如查询前N名的成员。
  6. 商品销售排行榜

    • 使用Sorted-Set,其中分数为销售数量,value值为商品编号。可以通过ZADD添加商品销售记录,ZINCRBY增加销量,ZRANGE获取前N名热门商品。
  7. 高并发下的统计分页显示

    • 在高并发场景下,使用Sorted-Set做统计分页显示,例如热评榜。使用时间作为分数插入,通过ZRANGEZREVRANGEZRANGEBYSCORE LIMIT按照分数查询分页。

这些应用场景展示了Redis Sorted-Set的灵活性和强大的功能,使其成为处理需要排序和排名的数据的理想选择。

相关文章:

Redis-结构化value对象的类型

文章目录 一、Redis的结构化value对象类型的介绍二、Redis的这些结构化value对象类型的通用操作查看指定key的数据类型查看所有的key判断指定key是否存在为已存在的key进行重命名为指定key设置存活时间pexpire与expire 查看指定Key的存活时间为指定key设置成永久存活 三、Redis…...

【QT】Qt对话框

个人主页~ Qt窗口属性~ Qt窗口 五、对话框2、Qt内置对话框&#xff08;1&#xff09;Message Box&#xff08;2&#xff09;QColorDialog&#xff08;3&#xff09;QFileDialog&#xff08;4&#xff09;QFontDialog&#xff08;5&#xff09;QInputDialog 五、对话框 2、Qt内…...

【计算机网络篇】数据链路层(14)虚拟局域网VLAN(概述,实现机制)

文章目录 &#x1f6f8;虚拟局域网VLAN&#x1f354;虚拟局域网VLAN的实现机制&#x1f95a;IEEE 802.1Q帧&#x1f95a;以太网交换机的接口类型&#x1f5d2;️例一&#xff1a;在一个交换机上不进行人为的VLAN划分&#xff0c;交换机各接口默认属于VLAN1且类型为Access的情况…...

伺服中的电子凸轮与追剪

一、机械凸轮 机械凸轮是一个具有曲线轮廓或凹槽的构件&#xff0c;它把运动特性传递给紧靠其边缘移动的推杆&#xff0c;推杆又带动机架做周期性运动。 凸轮的推杆位置跟随凸轮角度的周期性变化而变化&#xff0c;其运动特性与机械凸轮的外形相关&#xff0c;定义凸轮…...

Oracle 第22章:数据仓库与OLAP

第22章&#xff1a;数据仓库与OLAP 1. 数据仓库概念 数据仓库&#xff08;Data Warehouse, DW&#xff09; 是一个面向主题的、集成的、相对稳定的、反映历史变化的数据集合&#xff0c;用于支持管理决策。数据仓库中的数据通常来自不同的操作型系统或外部数据源&#xff0c;…...

在Ubuntu上安装TensorFlow与Keras

文章目录 1. 查看系统和Python版本信息1.1 查看Ubuntu版本信息1.2 查看Python版本信息 2. 安装pip2.1 下载get-pip.py2.2 运行get-pip.py2.3 查看pip版本 3. 安装Jupyter Notebook3.1 安装Jupyter Notebook3.2 运行Jupyter Notebook3.3 安装jupyter-core3.4 配置Jupyter Notebo…...

vue data变量之间相互赋值或进行数据联动

摘要&#xff1a; 使用vue时开发会用到data中是数据是相互驱动&#xff0c;经常会想到watch,computed&#xff0c;总结一下&#xff01; 直接赋值&#xff1a; 在 data 函数中定义的变量可以直接在方法中进行赋值。 export default {data() {return {a: 1,b: 2};},methods: {u…...

如何理解ref,toRef,和toRefs

1. ref ref 是 Vue 3 提供的一个用于创建响应式数据的 API。它可以用来创建简单的响应式变量&#xff0c;例如数字、字符串、布尔值或对象等。通过使用ref&#xff0c;当数据发生变化时&#xff0c;相关的组件视图会自动更新。 用法 创建响应式数据&#xff1a; import { ref …...

从单一到多元:揭秘 Hexo Diversity 主题的运行原理

揭秘 Hexo Diversity 主题的运行原理 一、 引言二、 Diversity 主题2.1 Hexo 控制台命令2.2 Hexo 核心 API2.3 运行原理2.3.1 多主题配置相关2.3.2 多主题执行指令 2.4 版本演进2.4.1 V1版本2.4.2 V2版本2.4.2.1 PC 端2.4.2.2 Phone 端 2.5 后续展望 三、 总结 一、 引言 众所…...

软考中级(系统集成项目管理工程师)案例分析计算题-笔记

案例分析计算题必拿分&#xff01;&#xff01; 1.成本进度管理 初中数学题&#xff0c;整了一堆缩写&#xff0c;容易给人绕晕 知道英文全称后就好理解了名词汇总&#xff1a; 英文缩写英文全称含义公式PVPlanned Value (计划值)按照计划到当前时间点需要花费的钱根据题目自…...

Docker打包自己项目推到Docker hub仓库(windows10)

一、启用Hyper-V和容器特性 1.应用和功能 2.点击程序和功能 3.启用或关闭Windows功能 4.开启Hyper-V 和 容器特性 记得重启生效&#xff01;&#xff01;&#xff01; 二、安装WSL2&#xff1a;写文章-CSDN创作中心https://mp.csdn.net/mp_blog/creation/editor/143057041 三…...

CesiumJS 案例 P20:监听鼠标滚轮、监听鼠标左键按下与松开、监听鼠标右键按下与松开、监听鼠标左击落点

CesiumJS CesiumJS 是一个开源的 JavaScript 库&#xff0c;它用于在网页中创建和控制 3D 地球仪&#xff08;地图&#xff09; CesiumJS 官网&#xff1a;https://www.cesium.com/ CesiumJS 下载地址&#xff1a;https://www.cesium.com/platform/cesiumjs/ CesiumJS API 文…...

如何使用Web-Check和cpolar实现安全的远程网站监测与管理

文章目录 前言1.关于Web-Check2.功能特点3.安装Docker4.创建并启动Web-Check容器5.本地访问测试6.公网远程访问本地Web-Check7.内网穿透工具安装8.创建远程连接公网地址9.使用固定公网地址远程访问 前言 本期给大家分享一个网站检测工具Web-Check&#xff0c;能帮你全面了解网…...

随机生成100组N个数并对比,C++,python,matlab,pair,std::piecewise_construct

随机生成100组N个数&#xff0c;数的范围是1到35&#xff0c;并检查是否包含目标数组的数字 python版本 import numpy as np def count_groups_containing_obj(N, obj):# 随机生成100组N个数&#xff0c;数的范围是1到35groups np.random.randint(1, 36, size(1000, N))#pri…...

python爬虫获取数据后的数据提取

文章目录 python爬虫中的数据提取1.Json格式数据的数据提取2.Html格式数据提取之bs4解析器如何使用快速使用对象的种类Tagname和attributes属性NavigableString(字符串)BeautifulSoupComment 子节点.contents.children.descendants 父节点.parent.parents 节点内容.string.stri…...

前段(vue)

目录 跨域是什么&#xff1f; SprinBoot跨域的三种解决方法 JavaScript 有 8 种数据类型&#xff0c; 金额的用什么类型。 前段 区别 JQuery使用$.ajax()实现异步请求 Vue 父子组件间的三种通信方式 Vue2 和 Vue3 存在多方面的区别。 跨域是什么&#xff1f; 跨域是指…...

pairwise算法之rank svm

众所周知&#xff0c;point-wise/pair-wise/list-wise是机器学习领域中重要的几种建模方法。比如&#xff0c;最常见的分类算法使用了point-wise&#xff0c;即一条样本对应一个label(0/1)&#xff0c;根据多条正负样本&#xff0c;使用交叉熵&#xff08;cross entropy&#x…...

SAP RFC 用户安全授权

一、SAP 通讯用户 对于RFC接口的用户&#xff0c;使用五种用户类型之一的“通讯”类型&#xff0c;这种类型的用户没有登陆SAPGUI的权限。 二、对调用的RFC授权 在通讯用户内部&#xff0c;权限对象&#xff1a;S_RFC中&#xff0c;限制进一步可以调用的RFC函数授权&#xff…...

记录新建wordpress站的实践踩坑:wordpress 上传源码新建站因权限问题导致无法访问、配置新站建站向导以及插件主题上传配置的解决办法

官方文档&#xff1a;How to install WordPress – Advanced Administration Handbook | Developer.WordPress.org 但是没写权限问题&#xff0c;可以下载到 wordpress官方包。 把下载的wordpresscn的包解压并上传到服务器目录下&#xff0c;但是因为是root上传导致了权限问题…...

为啥学习数据结构和算法

基础知识就像是一座大楼的地基&#xff0c;它决定了我们的技术高度。而要想快速做出点事情&#xff0c;前提条件一定是基础能力过硬&#xff0c;“内功”要到位。 想要通关大厂面试&#xff0c;千万别让数据结构和算法拖了后腿 我们学任何知识都是为了“用”的&#xff0c;是为…...

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周&#xff0c;有很多同学在写期末Java web作业时&#xff0c;运行tomcat出现乱码问题&#xff0c;经过多次解决与研究&#xff0c;我做了如下整理&#xff1a; 原因&#xff1a; IDEA本身编码与tomcat的编码与Windows编码不同导致&#xff0c;Windows 系统控制台…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解

突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 ​安全措施依赖问题​ GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

RocketMQ延迟消息机制

两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数&#xff0c;对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后&#xf…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望

文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例&#xff1a;使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例&#xff1a;使用OpenAI GPT-3进…...

边缘计算医疗风险自查APP开发方案

核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路

进入2025年以来&#xff0c;尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断&#xff0c;但全球市场热度依然高涨&#xff0c;入局者持续增加。 以国内市场为例&#xff0c;天眼查专业版数据显示&#xff0c;截至5月底&#xff0c;我国现存在业、存续状态的机器人相关企…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案

问题描述&#xff1a;iview使用table 中type: "index",分页之后 &#xff0c;索引还是从1开始&#xff0c;试过绑定后台返回数据的id, 这种方法可行&#xff0c;就是后台返回数据的每个页面id都不完全是按照从1开始的升序&#xff0c;因此百度了下&#xff0c;找到了…...

Java 二维码

Java 二维码 **技术&#xff1a;**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...

FFmpeg:Windows系统小白安装及其使用

一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】&#xff0c;注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录&#xff08;即exe所在文件夹&#xff09;加入系统变量…...