redis的基本数据类型(一)

news2024/11/18 11:25:02

redis的基本数据类型

  • 1、redis
    • 1.1、数据库分类
    • 1.2、NoSQL分类
    • 1.3、redis简介
    • 1.4、redis应用
    • 1.5、如何学习redis
  • 2、redis的安装
    • 2.1、Windows安装
      • 2.2.1、客户端redis管理工具
    • 2.2、Linux安装🔥
      • 2.2.1、redis核心文件
      • 2.2.2、启动方式
      • 2.2.3、redis桌面客户端
        • 1、redis命令行客户端
        • 2、图形化桌面客户端
  • 3、数据类型
    • 3.1、概况
    • 3.2、String类型
      • 3.2.1、常用的命令
      • 3.2.2、非常用命令
      • 3.2.3、应用场景
    • 3.3、Hash类型
      • 3.3.0、内部实现
      • 3.3.1、常用的命令
      • 3.3.2、应用场景
    • 3.4、List类型
      • 3.4.0、内部实现
      • 3.4.1、常用的命令
      • 3.4.2、非常用命令
      • 3.4.3、应用场景
    • 3.5、Set类型
      • 3.5.0、内部实现
      • 3.5.1、常用的命令
      • 3.5.2、非常用命令
      • 3.5.4、应用场景
    • 3.6、Zset类型
      • 3.6.1、内部实现
      • 3.6.1、常用的命令
      • 3.6.2、非常用命令
      • 3.6.4、应用场景
  • 4、Key的设计
    • 4.1、唯一性
    • 4.2、可读性
    • 4.3、时效性
    • 4.4、灵活性
  • 5、设置密码
    • 5.1、通过配置文件设置密码
    • 5.2、通过命令行设置密码
    • 5.3、更改密码
    • 5.4、取消密码
    • 4.4、灵活性

  • 参考视频:适合后端编程人员的Redis实战教程、redis应用场景、分布式缓存、Session管理、面试相关

1、redis

1.1、数据库分类

  • 目前数据库分:关系型数据库与非关系型数据库

  • 常用的关系型数据库: Oracle,MySQL,SqlServer,DB2

  • 常用的非关系数据库:Redis,MongoDB,ElasticSearch, Hbase,Neo4j

  • 那啥是非关系数据库呢?此处涉及到新名词:NoSQL

  • NoSQL最常见的解释是"non-relational", "Not Only SQL"也被很多人接受。NoSQL仅仅是一个概念,泛指非关系型的数据库,区别于关系数据库,它们不保证关系数据的ACID特性。

如商城网站中对商品数据频繁查询、对热搜商品的排行统计、订单超时问题、以及微信朋友圈音频、视频存储等相关使用传统的关系型数据库实现就显得非常复杂,虽然能实现相应功能但是在性能上却不是那么乐观。NoSQL这个技术门类的出现,更好的解决了这些问题,它告诉了世界不仅仅是sql。

1.2、NoSQL分类

分类举例典型应用场景数据模型优点缺点
键值(key-value)存储数据库redis内容缓存,主要用于处理大量数据的高访问负载,也用于一些日志系统等。通常用HashTable来实现查找速度快数据无结构化
列存储数据库HBase分布式的文件系统将同一列数据存在一起查找速度块,更容易进行分布式扩展功能相对局限
文档型数据库MongoDB查询性能不高,且缺乏统一的查询语法
图形数据库Infinite Graph社交网络,专注于构建关系图谱图结构利用图数据结构相关算法对整个图进行计算才能得到需要的信息

1.3、redis简介

redis是以key-value形式存储,和传统的关系型数据库不一样。不一定遵循传统数据库的一些基本要求。

优点:

  • 对数据高并发读写(直接是内存中进行读写的)
  • 对海量数据的高效率存储和访问
  • 对数据的可拓展性和高可用性
  • 单线程操作,每个操作都是原子操作,没有并发相关问题

缺点:

  • 无法做太复杂的关系数据库模型
  • redis(ACID处理非常简单)

redis 定位是缓存,提高数据读写速度,减轻对数据库存储和访问压力。redis是一个内存型的数据库

1.4、redis应用

  • 任务队列,如秒杀、抢购、购票排队等

  • 即时信息查询,如各位排行榜、各类网站访问统计、公交到站信息

  • 为热点数据加速查询(主要场景),如热点商品、热点新闻

  • 消息队列、分布式锁

1.5、如何学习redis

  • redis 在线入门 : http://try.redis.io/

  • redis 中文资料官网: http://www.redis.cn/

  • redis 中文教程:https://www.runoob.com/redis/redis-tutorial.html

  • redis官网:https://redis.io/download/

2、redis的安装

2.1、Windows安装

  • windows版:https://github.com/microsoftarchive/redis/releases/tag/win-3.2.100

傻瓜式安装,一直下一步就可以了,注意要添加到环境变量中

在这里插入图片描述

默认端口:

在这里插入图片描述

最大内存

在这里插入图片描述

测试是否成功:

  • win+r 输入 redis-cli

在这里插入图片描述

2.2.1、客户端redis管理工具

AnotherRedisDesktopManager 工具可以用来可视化管理redis,可以理解为 MySQL的 Sqlyog、Navicat等管理工具。

  • Github: GUI client], compatible with Linux, Windows, Mac. (github.com)
  • Gitee:AnotherRedisDesktopManager 发行版 - Gitee.com

在这里插入图片描述

下载完成后安装即可:

在这里插入图片描述

2.2、Linux安装🔥

  1. 进入Linux官网下载最新稳定版本:https://redis.io/download/

在这里插入图片描述

  1. 将其上传至 Linux 服务器目录下 /www/server/redis 中,并进行解压。

    我这里使用 wget 命令下载,和上述步骤作用一致

# 进入/www/server/redis目录下载
wget https://github.com/redis/redis/archive/7.2.3.tar.gz
http://github.com/redis/redis/archive/7.2.3.tar.gz
# 解压
tar -zxvf 7.2.3.tar.gz
  1. 进入到解压目录,执行编译命令
# 进入到解压目录
cd redis-7.2.3/

# 执行编译命令
make
  1. 进行安装
# 安装,默认是安装到 /usr/local/bin 目录
make install

在这里插入图片描述

共安装了三个组件:redis server服务器、redis-cli客户端与一个性能测试工具 benchmark

  1. 新建一个系统服务文件:
vi /etc/systemd/system/redis.service

内容如下:

[Unit]
Description=redis-server
After=network.target

[Service]
Type=forking
ExecStart=/usr/local/bin/redis-server /www/server/redis/redis-7.2.3/redis.conf
PrivateTmp=true

[Install]
WantedBy=multi-user.target
  1. 进入/www/server/redis/redis-7.2.3,先拷贝redis.conf,然后进行修改
# 拷贝
cp redis.conf redis.conf.back

修改redis.conf的配置

# 允许访问的地址,默认是127.0.0.1,会导致只能在本地访问。修改为0.0.0.0则可以在任意IP访问,生产环境不要设置为0.0.0.0
bind 0.0.0.0
# 守护进程,修改为yes后即可后台运行
daemonize yes 
  1. 然后重载系统服务
systemctl daemon-reload
  1. 现在,我们可以用下面这组命令来操作redis了:
# 启动
systemctl start redis
# 停止
systemctl stop redis
# 重启
systemctl restart redis
# 查看状态
systemctl status redis
  1. 执行下面的命令,可以让redis开机自启:
systemctl enable redis

在这里插入图片描述

  1. 查看 redis 版本
# 查看服务端版本
redis-server -v

# 查看客户端版本
redis-cli -v

2.2.1、redis核心文件

/usr/local/bin 目录中,可以看到如下文件:

在这里插入图片描述

  • redis-serve : 服务器启动命令
  • redis-cli : 命令行客户端
  • redis-benchmark : redis 性能测试工具
  • redis-check-aof :AOF文件修复工具
  • redis-check-dump :RDB文件检查工具(快照持久化文件)

通过echo $PATH 可以看到,/usr/local/bin 目录是存在于该系统变量中的,这样这些命令就可以在任意目录中执行了,这就是为什么我们在任意目录都可以直接使用redis-cli 进行命令行

在这里插入图片描述

2.2.2、启动方式

  • 方式一:前台启动,安装完成后,在任意目录输入redis-server命令即可启动Redis
redis-server

这种启动属于前台启动,会阻塞整个会话窗口,窗口关闭或者按下CTRL + C则Redis停止。不推荐使用。

  • 方式二:指定配置文件启动,如果要让Redis以后台方式启动,则必须修改Redis配置文件,就在我们之前解压的redis安装包下(/www/server/redis/redis-7.2.3),名字叫redis.conf

    1. 我们先将这个配置文件备份一份:

      cp redis.conf redis.conf.back
      
    2. 然后修改redis.conf文件中的一些配置:

      # 允许访问的地址,默认是127.0.0.1,会导致只能在本地访问。修改为0.0.0.0则可以在任意IP访问,生产环境不要设置为0.0.0.0
      bind 0.0.0.0
      # 守护进程,修改为yes后即可后台运行
      daemonize yes 
      # 密码,设置后访问Redis必须输入密码
      requirepass 1234
      
    3. Redis的其它常见配置:

      # 监听的端口
      port 6379
      # 工作目录,默认是当前目录,也就是运行redis-server时的命令,日志.持久化等文件会保存在这个目录
      dir .
      # 数据库数量,设置为1,代表只使用1个库,默认有16个库,编号0~15
      databases 1
      # 设置redis能够使用的最大内存
      maxmemory 512mb
      # 日志文件,默认为空,不记录日志,可以指定日志文件名
      logfile "redis.log"
      
    4. 启动Redis:

      # 进入redis安装目录 
      cd /www/server/redis/redis-7.2.3
      # 启动
      redis-server redis.conf
      
    5. 停止redis

      # 利用redis-cli来执行 shutdown 命令,即可停止 Redis 服务,
      # 因为之前配置了密码,因此需要通过 -u 来指定密码
      redis-cli -u 1234 shutdown
      
  • 方式三是开机自启,已经在2.2目录进行了设置

当给redis.conf 设置了密码requirepass 1234,则启动时需要auth 1234

在这里插入图片描述

2.2.3、redis桌面客户端

1、redis命令行客户端

Redis安装完成后就自带了命令行客户端:redis-cli,使用方式如下:

redis-cli [options] [commonds]

其中常见的options有:

  • -h 127.0.0.1:指定要连接的redis节点的IP地址,默认是127.0.0.1
  • -p 6379:指定要连接的redis节点的端口,默认是6379
  • -a 1234:指定redis的访问密码

其中的commonds就是Redis的操作命令,例如:

  • ping:与redis服务端做心跳测试,服务端正常会返回pong
2、图形化桌面客户端
  • AnotherRedisDesktopManager

  • 进去下载 exe 文件即可

  • 使用教程:https://blog.csdn.net/zsewer/article/details/129325846

注意:在连接的时候请确保服务器的防火墙端口打开6379,否则会连接不上

3、数据类型

3.1、概况

Redis支持的存储数据类型有很多:

  • 常用:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)

  • 不常用:HyperLogLog,Bitmap(位图),Bloom Filter(布隆过滤器),Geospatial(地理位置) ,Module(模块), Streams(流信息)

命令格式

类型命令keyvalue
setnamezhangsan

操作建议

  • Redis操作有点类似Java的Map集合,都是key-value形式存储数据,在学习过程中,可以进行类比。

  • 另外Redis中的key大部分为String类型,value值根据缓存数据结构可以选用:string,hash,list,set,zset等类型。

注意:下面讲的各种类型,表述的是缓存数据的value类型。

3.2、String类型

String类型包含多种类型的特殊类型,并且是二进制安全的,其值可以是数值,可以是字符串,也可以是二进制数据。

在这里插入图片描述

3.2.1、常用的命令

命令格式功能案例说明
set key value将key-value缓存redis中set name qxl设置name字段为qxl
get key从redis中获取key对应value值get name获取name字段对应的value
incr key将key对应value值 + 1incr age给age字段+1
decr key将key对应value值-1decr age给age字段-1
setex key seconds value将key-value缓存到redis中,seconds 秒后失效setex sex 10 man将sex字段设置为10s的man
ttl key查看key存活时间ttl sex查看sex字段对应的 value 存活时间
del key从redis中删除keydel name删除name字段
setnx key value如果key已经存,不做任何操作,如果key不存,直接添加setnx name xiaofei

普通字符串的基本操作:

# 设置 key-value 类型的值
> SET name lin
OK

# 根据 key 获得对应的 value
> GET name
"lin"

# 判断某个 key 是否存在
> EXISTS name
(integer) 1

# 返回 key 所储存的字符串值的长度
> STRLEN name
(integer) 3

# 删除某个 key 对应的值
> DEL name
(integer) 1

3.2.2、非常用命令

命令格式功能案例
incrby key increment给key对应值加incrementincrby age 10
mset k1 v1 k2 v2…批量添加k1v1 k2v2 key value对mset name dafei age 18
mget k1 k2…批量获取k1, k2的值mget name age
append key value在key对应的value值中拼+valueappend name yes
setrange key offset value修改key对应的value值,替换为指定value,冲offset索引位置开始setrange name 2 xx

批量设置:

# 批量设置 key-value 类型的值
> MSET key1 value1 key2 value2 
OK

# 批量获取多个 key 对应的 value
> MGET key1 key2 
1) "value1"
2) "value2"

计数器(字符串的内容为整数的时候可以使用):

# 设置 key-value 类型的值
> SET number 0
OK

# 将 key 中储存的数字值增一
> INCR number
(integer) 1

# 将key中存储的数字值加 10
> INCRBY number 10
(integer) 11

# 将 key 中储存的数字值减一
> DECR number
(integer) 10

# 将key中存储的数字值键 10
> DECRBY number 10
(integer) 0

过期(默认为永不过期):

# 设置 key 在 60 秒后过期(该方法是针对已经存在的key设置过期时间)
> EXPIRE name  60 
(integer) 1
# 查看数据还有多久过期
> TTL name 
(integer) 51

#设置 key-value 类型的值,并设置该key的过期时间为 60 秒
> SET key  value EX 60
OK
> SETEX key  60 value
OK

不存在就插入:

# 不存在就插入(not exists)
>SETNX key value
(integer) 1

3.2.3、应用场景

  1. 缓存对象:使用 String 来缓存对象有两种方式:

    • 直接缓存整个对象的 JSON,命令例子: SET user:1 '{"name":"xiaolin", "age":18}'
    • 采用将 key 进行分离为 user:ID:属性,采用 MSET 存储,用 MGET 获取各属性值,命令例子: MSET user:1:name xiaolin user:1:age 18 user:2:name xiaomei user:2:age 20
  2. 主页高频访问信息显示控制,例如新浪微博大V主页显示粉丝数与微博数量。这就是常规计数,计算访问次数、点赞次数、转发次数等。

  3. 共享session:

    • 通常我们在开发后台管理系统时,会使用 Session 来保存用户的会话(登录)状态,这些 Session 信息会被保存在服务器端,但这只适用于单系统应用,如果是分布式系统此模式将不再适用。

    • 例如用户一的 Session 信息被存储在服务器一,但第二次访问时用户一被分配到服务器二,这个时候服务器并没有用户一的 Session 信息,就会出现需要重复登录的问题,问题在于分布式系统每次会把请求随机分配到不同的服务器。

在这里插入图片描述

  • 出于负载均衡的考虑,分布式服务会将用户信息的访问均衡到不同服务器上,用户刷新一次访问可能会需要重新登录,为避免这个问题可以用redis将用户session集中管理, 在这种模式下只要保证redis的高可用和扩展性的,每次获取用户更新或查询登录信息都直接从redis中集中获取。

在这里插入图片描述

3.3、Hash类型

Hash 是一个键值对(key - value)集合,其中 value 的形式如: value=[{field1,value1},...{fieldN,valueN}]。Hash类型特别适合存储对象:

在这里插入图片描述

类似Java中:Map<String, Map<String, ?>> map

3.3.0、内部实现

Hash 类型的底层数据结构是由压缩列表或哈希表实现的:

  • 如果哈希类型元素个数小于 512 个,所有值小于 64 字节的话,Redis 会使用压缩列表作为 Hash 类型的底层数据结构;
  • 如果哈希类型元素不满足上面条件,Redis 会使用哈希表作为 Hash 类型的 底层数据结构

在 Redis 7.0 中,压缩列表数据结构已经废弃了,交由 listpack 数据结构来实现了

3.3.1、常用的命令

命令格式功能案例说明
hset key field value将field value对缓存到redis中hash中,键值为keyhset user name dafei给user中的name字段设置为dafei
hget key field从key对应hash列表中获取field字段hget user name获取user中的name字段
hexists key field判断key对应的hash列表是否存在 field字段hexists user age判断user中是否存在age字段
hdel key field删除key对应hash列表中field字段hdel user age删除user中的age字段
hincrby key field increment给key对应hash列表中field字段 + incrementhincrby user age 10给user中的age字段+10
hlen key查看key对应的hash列表field的数量hlen user查看user中的所有 key
hkeys key获取key对应的hash列表所有的field值hkeys user获取user中的所有 key
hvals key获取key对应的hash列表所有的field对应的value值hvals user获取user中的所有value
hgetall key获取key对应的hash列表中所有的field及其对应的value值hgetall user获取user中的所有 key 和 value
# 存储一个哈希表key的键值
HSET key field value   
# 获取哈希表key对应的field键值
HGET key field

# 在一个哈希表key中存储多个键值对
HMSET key field value [field value...] 
# 批量获取哈希表key中多个field键值
HMGET key field [field ...]       
# 删除哈希表key中的field键值
HDEL key field [field ...]    

# 返回哈希表key中field的数量
HLEN key       
# 返回哈希表key中所有的键值
HGETALL key 

# 为哈希表key中field键的值加上增量n
HINCRBY key field n  

Hash类型数据操作的注意事项:

  • Hash类型下的 value 只能存储字符串,不允许存储其他数据类型
  • Hash设计的初衷不是为了存储大量对象的,切记不可滥用。

3.3.2、应用场景

  • 缓存对象:Hash 类型的 (key,field, value) 的结构与对象的(对象id, 属性, 值)的结构相似,也可以用来存储对象。我们以用户信息为例,它在关系型数据库中的结构是这样的:

    uidnameage
    1Tom15
    2Jerry13

    我们可以使用如下命令,将用户对象的信息存储到 Hash 类型:

    # 存储一个哈希表uid:1的键值
    > HMSET uid:1 name Tom age 15
    2
    # 存储一个哈希表uid:2的键值
    > HMSET uid:2 name Jerry age 13
    2
    # 获取哈希表用户id为1中所有的键值
    > HGETALL uid:1
    1) "name"
    2) "Tom"
    3) "age"
    4) "15
    

    一般对象用 String + Json 存储,对象中某些频繁变化的属性可以考虑抽出来用 Hash 类型存储。

  • 电商网站购物车设计

    • 以客户id作为key,每位客户创建一个hash存储结构存储对应的购物车信息。将商品编号作为field,购买数量作为value进行存储

      keyvalue
      id{
      name: dafei
      field:001
      value:3
      }
    • 添加购物车:追加全新的field与value

    • 浏览购物车:遍历hash

    • 更改购物车数量:自增/自减,设置value值

    • 删除购物车商品:删除field

    • 清空购物车:删除key

3.4、List类型

  • List类型是一个链表结构的集合,其主要功能有push、pop、获取元素等。
  • 类似Java中:Map<String, List> map

在这里插入图片描述

3.4.0、内部实现

  • 如果列表的元素个数小于 512 个,列表每个元素的值都小于 64 字节,Redis 会使用压缩列表作为 List 类型的底层数据结构;
  • 如果列表的元素不满足上面的条件,Redis 会使用双向链表作为 List 类型的底层数据结构

但是在 Redis 3.2 版本之后,List 数据类型底层数据结构就只由 quicklist 实现了,替代了双向链表和压缩列表

3.4.1、常用的命令

命令格式功能案例说明
rpush key value从右边往key集合中添加value值rpush hobby java从右边向 hobby 集合中添加 java 字段
lrange key start stop从左边开始列表key集合,从start位置开始,stop位置结束lrange hobby 0 3
lrange hobby 0 -1
从左边开始罗列 hobby 集合下标 0-3 的字段
从左边开始罗列 hobby 集合下所有字段
lpush key value从左边往key集合中添加value值lpush hobby c++从左边向 hobby 集合中添加 c++ 字段
lpop key弹出key集合中最左边的数据lpop hobby弹出 hobby 集合中最左边的数据
rpop key弹出key集合中最右边的数据rpop hobby弹出 hobby 集合中最右边的数据
llen key获取列表长度llen hooby获取 hobby 集合的长度
# 将一个或多个值value插入到key列表的表头(最左边),最后的值在最前面
LPUSH key value [value ...] 
# 将一个或多个值value插入到key列表的表尾(最右边)
RPUSH key value [value ...]
# 移除并返回key列表的头元素
LPOP key     
# 移除并返回key列表的尾元素
RPOP key 

# 返回列表key中指定区间内的元素,区间以偏移量start和stop指定,从0开始
LRANGE key start stop

# 从key列表表头弹出一个元素,没有就阻塞timeout秒,如果timeout=0则一直阻塞
BLPOP key [key ...] timeout
# 从key列表表尾弹出一个元素,没有就阻塞timeout秒,如果timeout=0则一直阻塞
BRPOP key [key ...] timeout

3.4.2、非常用命令

命令格式功能案例
linsert key before pivot value操作key集合,在pivot值之前插入valuelinsert hobby before java c#
linsert key after pivot value操作key集合,在pivot值之后插入valuelinsert hobby after java c#
lset key index value操作key集合,更新索引index位置值为valuelset hobby 1 go
lrem key count value操作key集合,删除 count个 value值lrem hobby 3 go
ltrim key start stop操作key集合,从start到stop截取自列表ltrim hobby 2 4
lindex key index操作key集合,获取索引为index位置的数据lindex hobby 1

3.4.3、应用场景

  1. 用户收藏文章列表:
keyvalue
user_favor_article_list[aid1, aid2, aid3…]
  1. 消息队列:小林coding

3.5、Set类型

Set 类型是一个无序并唯一的键值集合,它的存储顺序不会按照插入的先后顺序进行存储。

在这里插入图片描述

Set 类型和 List 类型的区别如下:

  • List 可以存储重复元素,Set 只能存储非重复元素;
  • List 是按照元素的先后顺序存储元素的,而 Set 则是无序方式存储元素的。

3.5.0、内部实现

Set 类型的底层数据结构是由哈希表或整数集合实现的:

  • 如果集合中的元素都是整数且元素个数小于 512 (默认值,set-maxintset-entries配置)个,Redis 会使用整数集合作为 Set 类型的底层数据结构;
  • 如果集合中的元素不满足上面条件,则 Redis 使用哈希表作为 Set 类型的底层数据结构。

3.5.1、常用的命令

命令格式功能案例说明
sadd key members […]往key 集合中添加member元素sadd myset a b c给集合 myset 添加 a b c 元素
smembers key遍历key集合中所有的元素smembers myset遍历集合 myset
srem key members […]删除key集合中members元素srem myset a删除myset集合中的元素a
spop key count从key集合中随机弹出count个元素spop myset 1
# 往集合key中存入元素,元素存在则忽略,若key不存在则新建
SADD key member [member ...]
# 从集合key中删除元素
SREM key member [member ...] 
# 获取集合key中所有元素
SMEMBERS key
# 获取集合key中的元素个数
SCARD key

# 判断member元素是否存在于集合key中
SISMEMBER key member

# 从集合key中随机选出count个元素,元素不从key中删除
SRANDMEMBER key [count]
# 从集合key中随机选出count个元素,元素从key中删除
SPOP key [count]

3.5.2、非常用命令

命令格式功能案例
sdiff key1 key2返回key1中特有的元素(差集)sdiff key1 key2
sidiffstore dest key1 key2返回key1中特有的元素,并将返回值缓存到dest集合中sidiffstore dest key1 key2
sinter key1 key2返回key1跟key2集合的交集sinter key1 key2
sinterstore dest key1 key2返回key1跟key2集合的交集,并将返回值缓存到dest集合中sinterstore dest key1 key2
sunion key1 key2返回key1跟key2集合的并集sunion key1 key2
sunionstore dest key1 key2返回key1跟key2集合的并集,并将返回值缓存到dest集合中sunionstore dest key1 key2
smove source destination member将source集合中member元素移动到destination集合中smove key1 key2 aa
sismember key member判断member元素是否在key集合中sismember key1 aa
srandmember key count随机获取set集合中count 个元素srandmem
# 交集运算
SINTER key [key ...]
# 将交集结果存入新集合destination中
SINTERSTORE destination key [key ...]

# 并集运算
SUNION key [key ...]
# 将并集结果存入新集合destination中
SUNIONSTORE destination key [key ...]

# 差集运算
SDIFF key [key ...]
# 将差集结果存入新集合destination中
SDIFFSTORE destination key [key ...]

3.5.4、应用场景

集合的主要几个特性,无序、不可重复、支持并交差等操作。因此 Set 类型比较适合用来数据去重和保障数据的唯一性,还可以用来统计多个集合的交集、错集和并集等,当我们存储的数据是无序并且需要去重的情况下,比较适合使用集合类型进行存储。

Set 的差集、并集和交集的计算复杂度较高,在数据量较大的情况下,如果直接执行这些计算,会导致 Redis 实例阻塞

在主从集群中,为了避免主库因为 Set 做聚合计算(交集、差集、并集)时导致主库被阻塞,我们可以选择一个从库完成聚合统计,或者把数据返回给客户端,由客户端来完成聚合统计。

  1. 点赞场景:Set 类型可以保证一个用户只能点一个赞,这里举例子一个场景,key 是文章id,value 是用户id。

    # uid:1 、uid:2、uid:3 三个用户分别对 article:1 文章点赞了
    # uid:1 用户对文章 article:1 点赞
    > SADD article:1 uid:1
    (integer) 1
    # uid:2 用户对文章 article:1 点赞
    > SADD article:1 uid:2
    (integer) 1
    # uid:3 用户对文章 article:1 点赞
    > SADD article:1 uid:3
    (integer) 1
    
    # uid:1 取消了对 article:1 文章点赞。
    > SREM article:1 uid:1
    (integer) 1
    
    # 获取 article:1 文章所有点赞用户 
    > SMEMBERS article:1
    1) "uid:3"
    2) "uid:2"
    
    # 获取 article:1 文章的点赞用户数量
    > SCARD article:1
    (integer) 2
    
    # 判断用户 uid:1 是否对文章 article:1 点赞了
    > SISMEMBER article:1 uid:1
    (integer) 0  # 返回0说明没点赞,返回1则说明点赞了
    
  2. 共同关注:Set 类型支持交集运算,所以可以用来计算共同关注的好友、公众号等

    # key 可以是用户id,value 则是已关注的公众号的id。
    # uid:1 用户关注公众号 id 为 5、6、7、8、9,uid:2 用户关注公众号 id 为 7、8、9、10、11
    
    # uid:1 用户关注公众号 id 为 5、6、7、8、9
    > SADD uid:1 5 6 7 8 9
    (integer) 5
    # uid:2  用户关注公众号 id 为 7、8、9、10、11
    > SADD uid:2 7 8 9 10 11
    (integer) 5
    
    # 获取共同关注
    > SINTER uid:1 uid:2
    1) "7"
    2) "8"
    3) "9"
    
    # 给 uid:2 推荐 uid:1 关注的公众号
    > SDIFF uid:1 uid:2
    1) "5"
    2) "6"
    
    # 验证某个公众号是否同时被 uid:1 或 uid:2 关注:
    > SISMEMBER uid:1 5
    (integer) 1 # 返回0,说明关注了
    > SISMEMBER uid:2 5
    (integer) 0 # 返回0,说明没关注
    
  3. 抽奖活动:存储某活动中中奖的用户名 ,Set 类型因为有去重功能,可以保证同一个用户不会中奖两次

    # key为抽奖活动名,value为员工名称,把所有员工名称放入抽奖箱
    >SADD lucky Tom Jerry John Sean Marry Lindy Sary Mark
    (integer) 5
    
    # 如果允许重复中奖,可以使用 SRANDMEMBER 命令
    # 抽取 1 个一等奖:
    > SRANDMEMBER lucky 1
    1) "Tom"
    # 抽取 2 个二等奖:
    > SRANDMEMBER lucky 2
    1) "Mark"
    2) "Jerry"
    # 抽取 3 个三等奖:
    > SRANDMEMBER lucky 3
    1) "Sary"
    2) "Tom"
    3) "Jerry"
    

    如果不允许重复中奖,可以使用 SPOP 命令

    # 抽取一等奖1个
    > SPOP lucky 1
    1) "Sary"
    # 抽取二等奖2个
    > SPOP lucky 2
    1) "Jerry"
    2) "Mark"
    # 抽取三等奖3个
    > SPOP lucky 3
    1) "John"
    2) "Sean"
    3) "Lindy"
    

3.6、Zset类型

  • Zset 类型(有序集合类型)相比于 Set 类型多了一个排序属性 score(分值),对于有序集合 ZSet 来说,每个存储元素相当于有两个值组成的,一个是有序集合的元素值,一个是排序值。
  • 有序集合保留了集合不能有重复成员的特性(分值可以重复),但不同的是,有序集合中的元素可以排序。

在这里插入图片描述

3.6.1、内部实现

Zset 类型的底层数据结构是由压缩列表或跳表实现的:

  • 如果有序集合的元素个数小于 128 个,并且每个元素的值小于 64 字节时,Redis 会使用压缩列表作为 Zset 类型的底层数据结构;
  • 如果有序集合的元素不满足上面的条件,Redis 会使用跳表作为 Zset 类型的底层数据结构;

在 Redis 7.0 中,压缩列表数据结构已经废弃了,交由 listpack 数据结构来实现了。

3.6.1、常用的命令

命令格式功能案例说明
zadd key score member往key集合中添加member元素,分数为scorezadd players 100 a向players集合添加a元素,分数为100
zincrby key increment member将key集合中的member元素 分数 + incrementzadd players 100 a向players集合的a元素分数+100
zrange key start stop [withscores]将key集合中的元素按分数升序排列 [显式分数]zrange players 0 -1 withscores
zrevrange key start stop [withscores]将key集合中的元素按分数降序排列 [显式分数]zrevrange players 0 -1 withscores
zrank key member返回member元素在key结合中的正序排名zrank players a返回players集合中a元素的正序排名
zrevrank key member返回member元素在key结合中的倒序排名zrevrank players a
zcard key返回key集合元素个数zcard players
# 往有序集合key中加入带分值元素
ZADD key score member [[score member]...]   
# 往有序集合key中删除元素
ZREM key member [member...]                 
# 返回有序集合key中元素member的分值
ZSCORE key member
# 返回有序集合key中元素个数
ZCARD key 

# 为有序集合key中元素member的分值加上increment
ZINCRBY key increment member 

# 正序获取有序集合key从start下标到stop下标的元素
ZRANGE key start stop [WITHSCORES]
# 倒序获取有序集合key从start下标到stop下标的元素
ZREVRANGE key start stop [WITHSCORES]

# 返回有序集合中指定分数区间内的成员,分数由低到高排序。
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]

# 返回指定成员区间内的成员,按字典正序排列, 分数必须相同。
ZRANGEBYLEX key min max [LIMIT offset count]
# 返回指定成员区间内的成员,按字典倒序排列, 分数必须相同
ZREVRANGEBYLEX key max min [LIMIT offset count]

Zset 运算操作(相比于 Set 类型,ZSet 类型没有支持差集运算):

# 并集计算(相同元素分值相加),numberkeys一共多少个key,WEIGHTS每个key对应的分值乘积
ZUNIONSTORE destkey numberkeys key [key...] 
# 交集计算(相同元素分值相加),numberkeys一共多少个key,WEIGHTS每个key对应的分值乘积
ZINTERSTORE destkey numberkeys key [key...]

3.6.2、非常用命令

命令格式功能案例
zrangebyscore key min max [withscores]按[min, max) 分数范围返回key集合中元素(正序)zrangebyscore players 200 300 withscores
zrevrangebyscore key min max [withscores]按[min, max) 分数范围返回key集合中元素(倒序)zrevrangebyscore players 200 300 withscores
zrem key member删除key集合中member元素与分数zrem players a
zremrangebyscore key min max withscores按[min, max) 分数范围删除key集合中元素zremrangebyscore players 200 300 withscores
zremrangebyrank key start stop删除key集合正序排名落在[start, stop) 范围元素zremrangebyrank players 10 20
zcount key min max按照分数范围[min, max]统计key集合中元素个数zcount players 100 300

3.6.4、应用场景

​ Zset 类型(Sorted Set,有序集合) 可以根据元素的权重来排序,我们可以自己来决定每个元素的权重值。比如说,我们可以根据元素插入 Sorted Set 的时间确定权重值,先插入的元素权重小,后插入的元素权重大。

​ 在面对需要展示最新列表、排行榜等场景时,如果数据更新频繁或者需要分页显示,可以优先考虑使用 Sorted Set。

  1. 排行榜:我们以博文点赞排名为例,小林发表了五篇博文,分别获得赞为 200、40、100、50、150。

    # arcticle:1 文章获得了200个赞
    > ZADD user:xiaolin:ranking 200 arcticle:1
    (integer) 1
    # arcticle:2 文章获得了40个赞
    > ZADD user:xiaolin:ranking 40 arcticle:2
    (integer) 1
    # arcticle:3 文章获得了100个赞
    > ZADD user:xiaolin:ranking 100 arcticle:3
    (integer) 1
    # arcticle:4 文章获得了50个赞
    > ZADD user:xiaolin:ranking 50 arcticle:4
    (integer) 1
    # arcticle:5 文章获得了150个赞
    > ZADD user:xiaolin:ranking 150 arcticle:5
    (integer) 1
    

    文章 arcticle:4 新增一个赞,可以使用 ZINCRBY 命令(为有序集合key中元素member的分值加上increment):

    > ZINCRBY user:xiaolin:ranking 1 arcticle:4
    "51"
    

    查看某篇文章的赞数,可以使用 ZSCORE 命令(返回有序集合key中元素个数):

    > ZSCORE user:xiaolin:ranking arcticle:4
    "50"
    

    获取小林文章赞数最多的 3 篇文章,可以使用 ZREVRANGE 命令(倒序获取有序集合 key 从start下标到stop下标的元素):

    # WITHSCORES 表示把 score 也显示出来
    > ZREVRANGE user:xiaolin:ranking 0 2 WITHSCORES
    1) "arcticle:1"
    2) "200"
    3) "arcticle:5"
    4) "150"
    5) "arcticle:3"
    6) "100"
    

    获取小林 100 赞到 200 赞的文章,可以使用 ZRANGEBYSCORE 命令(返回有序集合中指定分数区间内的成员,分数由低到高排序):

    > ZRANGEBYSCORE user:xiaolin:ranking 100 200 WITHSCORES
    1) "arcticle:3"
    2) "100"
    3) "arcticle:5"
    4) "150"
    5) "arcticle:1"
    6) "200"
    

4、Key的设计

Redis 的key 设计讲究4个性:

4.1、唯一性

Redis 类似Map集合,key必须保证唯一,缓存同一个key时,后者会覆盖前者,所以必须要求唯一,那如何保证唯一呢?最常用的方式:使用缓存数据的主键作为key

比如:缓存员工信息

keyvalue
1员工1
2员工2

其中的1, 2 是员工的id

4.2、可读性

可读性是保证Redis的key能做到见名知意,上面的员工id1, 员工id2 虽说能保证key唯一,但可读性非常差,维护key时,无法从1, 2中快速判断该key对应value值。所以一一般在保证key唯一的前提下,给key加上前缀:

keyvalue
employee_info:id1员工1
employee_info:id2员工2

employee_info:id1employee_info:id2 这样子设计key,可读性就好多了。

  • 通用玩法:业务模块名:业务逻辑含义:其他:value类型
keyvalue
employee :base.info:id1:hash员工对象信息

业务模块名:表示该key属于哪个功能模块

业务逻辑含义段:这里可以使用 . 分开, 具体业务逻辑表示

  • 比如:缓存员工权限:employee:auth.permission:id1:set 员工权限集合

其他:一般设置唯一标识,比如主键

value类型:key对应value类型值,提高可读性。

4.3、时效性

redis key一定要设置过期时间。要跟自己的业务场景,需要对key设置合理的过期时间。可以在写入key时,就要追加过期时间;也可以在按照需要动态设置。

这里要注意:

  • 不设置过期时间,这种key为永久key,会一直占用内存不释放,时间久了,数量一多,就容易达到服务器的内存上限,导致宕机,开发时一般配合Key过期策略使用哦。
  • key的时效性设置,必须根据业务场景进行评估,设置合理有效期;

4.4、灵活性

这个难介绍,一般key保证唯一时,可以使用主键,有的使用一个主键不能表达出全部意思,可以使用联合主键。

比如:id为1的朋友圈下id为A的评论。

keyvalue
post:1:reply:A评论内容
post:1:reply:B评论内容

5、设置密码

下面我们将介绍两种常用的方法来为Redis设置密码:

5.1、通过配置文件设置密码

在Redis的配置文件redis.conf中,可以通过以下步骤来设置密码:

  1. 打开redis.conf文件(我的是在./www/server/redis/redis-7.2.3目录下)
  2. 找到并取消注释requirepass

在这里插入图片描述

  1. requirepass后面添加你想要设置的密码,如requirepass 1234

  2. 保存并关闭配置文件。

  3. 重新启动Redis服务器,使密码生效。

5.2、通过命令行设置密码

除了通过配置文件,还可以直接通过命令行来为Redis设置密码。打开终端并输入以下命令:

redis-cli

接着,在命令行中输入以下命令来设置密码:

config set requirepass mypassword

运行上述命令后,Redis将返回OK表示密码设置成功。

验证:

  • 在redis命令行中,使用auth mypassword来验证密码
  • 如果密码正确,Redis将返回OK,表示密码验证成功。

5.3、更改密码

  1. 在redis命令行中更改
config set requirepass newpassword

替换newpassword为你想要设置的新密码。

在这里插入图片描述

5.4、取消密码

  1. 在redis命令行中更改
config set requirepass ""

运行上述命令后,Redis将返回OK,表示密码已成功取消。

多,就容易达到服务器的内存上限,导致宕机,开发时一般配合Key过期策略使用哦。

  • key的时效性设置,必须根据业务场景进行评估,设置合理有效期;

4.4、灵活性

这个难介绍,一般key保证唯一时,可以使用主键,有的使用一个主键不能表达出全部意思,可以使用联合主键。

比如:id为1的朋友圈下id为A的评论。

keyvalue
post:1:reply:A评论内容
post:1:reply:B评论内容

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1479068.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

transformer--编码器2(前馈全连接层、规范化层、子层链接结构、编码器层、编码器)

前馈全连接层 什么是前馈全连接层: 在Transformer中前馈全连接层就是具有两层线性层的全连接网络 前馈全连接层的作用: 考虑注意力机制可能对复杂过程的拟合程度不够,通过增加两层网络来增强模型的能力 code # 前馈全连接层 class PositionwiseFeedForward(nn.Module):de…

LNMP架构(搭建论坛+博客)

目录 一、LNMP架构概述 1、LNMP架构的概念 2、LNMP架构的优点 二、编译安装nginx软件 1、准备工作 1.1 关闭防火墙 1.2 安装依赖包 1.3 创建运行nginx用户 1.4 压缩包解压 2、编译与安装 3、添加nginx自启动文件 三、编译安装mysql软件 1、准备工作 1.1 安装mysq…

HTTPS的加密过程

文章目录 前言一、为什么需要加密&#xff1f;二、只用对称加密可以吗&#xff1f;三、只使用非对称加密四、双方都使用非对称加密五、使用非对称加密对称加密六、引入证书1.如何放防止数字证书被篡改&#xff1f;2.中间人有可能篡改该证书吗&#xff1f;3.中间人有可能掉包该证…

环境配置 |Jupyter lab/Jupyter Notebook 安装与设置

ipynb使用Jupyterlab/Jupyter Notebook 来编写Python程序时的文件,在使用时,可以现转换为标准的.py的python文件 1.Jupyter Lab 1.1.下载安装 环境&#xff1a;Linux pip install jupyterlab 1.2.使用 jupyter lab 点击后进入 1.3.jupyter lab更换内核 因为我的是在anac…

arm板运行程序时寻找动态库的路径设置

问题&#xff1a;error while loading shared libraries: libQt5Widgets.so.5: cannot open shared object file&#xff1f; 第一种方法---- 解决&#xff1a; ①复制需要用到的arm库到板子上。 ②pwd指令获取该库的绝对路径&#xff0c;把路径复制到/etc/ld.so.conf文件 ③输…

google最新大语言模型gemma本地化部署

Gemma是google推出的新一代大语言模型&#xff0c;构建目标是本地化、开源、高性能。 与同类大语言模型对比&#xff0c;它不仅对硬件的依赖更小&#xff0c;性能却更高。关键是完全开源&#xff0c;使得对模型在具有行业特性的场景中&#xff0c;有了高度定制的能力。 Gemma模…

网络传输基本流程(封装,解包)+图解(同层直接通信的证明),报头分离问题,协议定位问题,协议多路复用

目录 网络传输基本流程 引入 封装 过程梳理 图解 报文 解包 过程梳理 图解 -- 同层直接通信的证明 总结 解包时的报头分离问题 举例 -- 倒水 介绍 自底向上传输时的协议定位问题 介绍 解决方法 协议多路复用 介绍 优势 网络传输基本流程 引入 首先,我们明确…

Python学习 --- 面向对象

1.什么是对象 1.Python中创建类的关键字是 class 2.类的成员方法 1.函数是写在类外面的,方法则是写在类里面的 1.上面这一段代码中就展示了如何在方法中访问类的成员变量: self.成员变量名 3.魔术方法 魔术方法其实就是python中的类中的内置方法,下面这几个只是我们比较常…

02| JVM堆中垃圾回收的大致过程

如果一直在创建对象&#xff0c;堆中年轻代中Eden区会逐渐放满&#xff0c;如果Eden放满&#xff0c;会触发minor GC回收&#xff0c;创建对象的时GC Roots&#xff0c;如果存在于里面的对象&#xff0c;则被视为非垃圾对象&#xff0c;不会被此次gc回收&#xff0c;就会被移入…

深度神经网络联结主义的本质

一、介绍 在新兴的人工智能 (AI) 领域&#xff0c;深度神经网络 (DNN) 是一项里程碑式的成就&#xff0c;突破了机器学习、模式识别和认知模拟的界限。这一技术奇迹的核心是一个与认知科学本身一样古老的思想&#xff1a;联结主义。本文深入探讨了联结主义的基本原理&#xff0…

阿里云启动实例进入了急救模式解决办法

相关文档 问题描述 通过远程连接软件无法登录Linux实例&#xff0c;通过使用管理终端连接Linux实例远程连接时&#xff0c;发现系统进入到急救模式&#xff08;emergency mode&#xff09;&#xff0c;且出现报错。 CentOS实例报如下错误。 systemctl default to try again…

小(2)型土石坝安全监测设施配置详解

小(2)型土石坝的安全监测是确保大坝稳定、安全运行的重要环节。为此&#xff0c;合理配置安全监测设施显得尤为重要。以下是对小(2)型土石坝安全监测设施配置的详细介绍。 一、渗流量监测 渗流量是反映大坝安全状况的关键指标之一。为准确监测渗流量&#xff0c;我们采用仪器量…

PackagingTool_x64_v2.0.1.0图片转档打包二进制文件合并字库生成图片软件介绍

继去年12月份发布的打包软件PackagingTool v1.4.0.2之后&#xff0c;今年再度投入精力&#xff0c;完善了软件功能&#xff0c;同时开发了几个更加实用的工具&#xff0c;可助力UI界面的设计开发。当前最新版本为PackagingTool_x64_v2.0.1.0&#xff0c;该版本主界面如下&#…

php基础学习之错误处理(其二)

在实际应用中&#xff0c;开发者当然不希望把自己开发的程序的错误暴露给用户&#xff0c;一方面会动摇客户对己方的信心&#xff0c;另一方面容易被攻击者抓住漏洞实施攻击&#xff0c;同时开发者本身需要及时收集错误&#xff0c;因此需要合理的设置错误显示与记录错误日志 一…

全国夜间灯光指数数据、GDP密度分布、人口密度分布、土地利用数据、降雨量数据

引言 DMSP/OLS的1992-2013年全球遥感影像&#xff0c;包括三种非辐射定标的夜间灯光影像。三种全年平均影像分别是&#xff1a;无云观测频数影像、平均灯光影像和稳定灯光影像。目前地理遥感生态网可提供全国稳定灯光影像免费下载。稳定灯光影像是标定夜间平均灯光强度的年度栅…

java 大学生社团管理系统Myeclipse开发mysql数据库web结构jsp编程计算机网页项目

一、源码特点 java 大学生社团管理系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysql5…

概率基础——多元正态分布

概率基础——多元正态分布 介绍 多元正态分布是统计学中一种重要的多维概率分布&#xff0c;描述了多个随机变量的联合分布。在多元正态分布中&#xff0c;每个随机变量都服从正态分布&#xff0c;且不同随机变量之间可能存在相关性。本文将以二元标准正态分布为例&#xff0…

免费pr素材(漂亮的波浪图形动画背景视频素材)下载

10个漂亮的免费波浪图形动画pr素材&#xff0c;PR动态背景视频素材mogrt下载。 特点&#xff1a;Premiere Pro 2023或更高版本&#xff0c;超高清分辨率&#xff1a;38402160&#xff0c;每秒25帧的帧速率&#xff0c;包括教程视频。来自pr素材网&#xff0c;下载地址&#xff…

数字孪生与智慧交通的融合发展:推动交通行业数字化转型,构建智慧城市新生态

随着信息技术的快速发展和城市化进程的深入推进&#xff0c;交通行业正面临着前所未有的机遇与挑战。传统的交通管理模式已难以满足日益增长的交通需求&#xff0c;而数字化转型则成为了推动交通行业创新发展的必由之路。数字孪生技术作为一种前沿的信息技术手段&#xff0c;为…

Echarts图标初始化实例的时候传入的参数

一般我们初始化实例的时候都是这么写的 其实echarts.init()还可以传入另外两个选项&#xff0c; 第二个选项为主题色 分为深色主题以及浅色主题&#xff0c;默认为浅色主题&#xff0c;传入light 深色主题的话可以传入dark 第三个选项为option 但是用得比较多的是渲染器ren…