[TOC]
12:redis【瑞迪斯】数据类型
今日工作任务路线图

一、工作场景
1.1 电商平台场景
在电商平台中,会大量使用 Redis【瑞迪斯】 来提升性能和处理并发。用字符串类型缓存商品的基本信息,减轻数据库压力;用列表类型实现消息队列,处理订单任务;用散列类型存储商品的多维度属性,方便单独查询和修改;用集合类型实现商品标签系统,便于用户根据标签搜索商品;用有序集合类型实现商品销量排行榜。
1.2 社交平台场景
社交平台利用 Redis【瑞迪斯】 来实现各种功能。字符串类型用于存储用户的会话信息,保证用户登录状态一致;列表类型存储用户的动态历史记录,方便用户查看;散列类型存储用户的详细资料;集合类型存储用户的好友列表,实现共同好友推荐;有序集合类型实现用户活跃度排行榜。
二、为什么学
学习 Redis【瑞迪斯】 数据类型具有多方面重要意义。从性能上看,Redis【瑞迪斯】 作为基于内存的键值型 NoSQL 数据库,读写速度极快,官方数据显示读取速度达 110000 次/秒,写速度 81000 次/秒,掌握其数据类型能让我们在开发中充分利用这一优势,提升系统性能。
从应用场景来说,不同数据类型适用场景广泛。比如字符串类型可用于缓存、计数器、分布式锁等;列表类型能实现消息队列、排行榜、历史记录存储等;散列类型适合存储用户信息、商品属性等;集合类型可用于用户管理、唯一性检查等;有序集合类型能实现排行榜、分数统计等。学习这些数据类型,能让我们在面对各种业务需求时,选择合适的数据类型解决问题。
从就业角度看,Redis【瑞迪斯】 在互联网领域应用广泛,掌握 Redis【瑞迪斯】 数据类型及其应用,能增强我们在职场上的竞争力,为从事相关工作打下坚实基础。
三、搭建redis【瑞迪斯】 服务器
当前任务环节

3.1 什么是redis【瑞迪斯】
Redis【瑞迪斯】 即远程字典服务,是开源的基于内存的键值型NoSQL数据库,用C语言编写。它将数据存于内存,读写快,官方数据显示读取速度达110000次/秒,写速度81000次/秒 。支持字符串、哈希、列表、集合、有序集合等丰富数据结构,每种都有专门操作命令。提供RDB和AOF两种持久化机制,还支持主从复制、哨兵机制、集群模式等。采用单线程架构结合IO多路复用技术处理请求,避免多线程开销。广泛用于缓存、会话管理、排行榜等场景。
3.2 准备环境
克隆1台新虚拟机
| 主机名 | IP地址 | 说明 |
|---|---|---|
| redis64 | 192.168.90.64 | redis服务器 |
修改IP地址和主机名
[root@redis64 ~]# hostnamectl【厚斯内姆 ctl】 set-hostname【赛特-厚斯内姆】 redis64[root@redis64 ~]# nmcli connection【肯耐申】 modify【莫迪fái】ens160 ipv4.addresses【额拽西斯】 192.168.90.64/24 autoconnect【奥特欧 坑聂特】 yes[root@redis64~]# nmcli connection【肯耐申】 up ens1603.3 安装和运行redis【瑞迪斯】
命令操作如下所示:
#安装redis【瑞迪斯】[root@redis64 ~]# yum -y install【因-斯多】 redis【瑞迪斯】
#查看redis【瑞迪斯】 版本[root@redis64 ~]# rpm -q redis【瑞迪斯】redis-6.2.18-1.el9_6.x86_64
#设置开机自启,并立即启动[root@redis64 ~]# systemctl【西斯屯-ctl】 enable【ing 内 步】 redis【瑞迪斯】 --now
#查看redis端口[root@redis64 ~]# netstat【劣 s 塔】 -antlup | grep【哥瑞普】 redis【瑞迪斯】tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 34578/redis-servertcp6 0 0 ::1:6379 :::* LISTEN 34578/redis-server3.4 连接redis【瑞迪斯】 服务
命令操作如下所示:
#连接redis【瑞迪斯】[root@redis64 ~]# redis-cli
#检查能否正在访问127.0.0.1:6379> pingPONG
#断开连接127.0.0.1:6379> exit【诶西特】[root@redis64 ~]#完整的连接redis
#发现通过IP无法连接[root@redis64 ~]# redis-cli -h 192.168.90.64 -p 6379Could not connect to Redis at 192.168.90.64:6379: Connection refused修改redis【瑞迪斯】 配置文件,使得redis【瑞迪斯】 可以被任何机器连接
#修改前[root@redis64 ~]# vim /etc/redis/redis.conf 72 # IF YOU ARE SURE YOU WANT YOUR INSTANCE TO LISTEN TO ALL THE INTERFACES 73 # JUST COMMENT OUT THE FOLLOWING LINE. 74 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 75 bind 127.0.0.1 -::1 #修改75行
#修改后[root@redis64 ~]# vim /etc/redis/redis.conf 72 # IF YOU ARE SURE YOU WANT YOUR INSTANCE TO LISTEN TO ALL THE INTERFACES 73 # JUST COMMENT OUT THE FOLLOWING LINE. 74 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 75 bind 0.0.0.0
#修改配置文件后重启[root@redis64 ~]# systemctl【西斯屯-ctl】 restart【 率 s 达r】 redis【瑞迪斯】
#现在可以连接[root@redis64 ~]# redis-cli -h 192.168.90.64 -p 6379192.168.90.64:6379> pingPONG3.5 给redis【瑞迪斯】 设置密码
命令操作如下所示:
#修改903行[root@redis64 ~]# vim /etc/redis/redis.conf 900 # The requirepass is not compatable with aclfile option and the ACL LOAD 901 # command, these will cause requirepass to be ignored. 902 # 903 requirepass 123456
#修改后重启[root@redis64 ~]# systemctl【西斯屯-ctl】 restart【 率 s 达r】 redis【瑞迪斯】
#连接redis【瑞迪斯】[root@redis64 ~]# redis-cli
# 这时候操作失败127.0.0.1:6379> ping(error) NOAUTH Authentication required.
# 输入密码认证127.0.0.1:6379> auth 123456OK127.0.0.1:6379> pingPONG四、字符串类型(string【斯jǘn】 类型)
当前任务环节

4.1 应用场景
Redis【瑞迪斯】 字符串类型是最基本的数据类型,支持存储整数、浮点数和字符串,适用于多种应用场景,以下是一些常见的应用场景:
- 缓存:可存储用户名、密码、会话标识符等简短字符串,也能缓存数据库查询结果、网页内容、用户信息等常用数据,减轻数据库压力,提高访问速度。例如在商品系统中,用 Redis【瑞迪斯】 String【斯jǘn】 类型缓存商品的静态信息,商品信息更新时,同步更新或使缓存失效 。
- 计数器:利用 incr【因kuì儿】 和 decr【迪kuì儿】 命令实现计数功能,适用于统计网页访问量、点赞数、文章浏览量、商品库存数量等。比如在文章浏览量统计中,每次文章被访问,文章 ID 对应的浏览次数在 Redis【瑞迪斯】 中递增,还可定期将浏览次数同步到数据库用于历史数据分析 。
- 分布式锁:结合 setNX 命令,使用字符串实现简单的分布式锁,保证在分布式系统中的数据一致性和并发控制。例如在电商的秒杀活动或库存管理中,确保同一时间只有一个进程或线程可以修改共享资源,避免数据不一致 。
- 共享会话(Session【塞-神】):在分布式 Web 应用里,可集中管理用户的 Session【塞-神】 信息(如登录信息),确保用户无论访问哪台服务器都能保持一致的会话状态,避免因负载均衡到不同服务器而需重新登录。
- 手机验证码:存储短信验证码并设置过期时间,还可限制用户获取验证码的频率,例如限制每分钟获取不超过 5 次 。
4.2 设置单个值
设置单个值,命令格式:
set【赛特】 key【kì】 value【挖柳】
查看key【kì】 对应的值
get【脚(白话)特】 key【kì】
[root@redis64 ~]# redis-cli -h 192.168.90.64 -p 6379192.168.90.64:6379> auth 123456OK192.168.90.64:6379> set【赛特】 school【斯故】 moershiOK192.168.90.64:6379> get【脚(白话)特】 school【斯故】"moershi"4.4 设置多个值
设置多个值,命令格式:
mset key1 value【挖柳】1 key2 value【挖柳】2 key3 value【挖柳】3…
查看多个key【kì】 对应的值
mget key1 key2 key3
192.168.90.64:6379> mset name jam age 30 class yjs001OK192.168.90.64:6379> mget name age class1) "jam"2) "30"3) "yjs001"4.5 设置值的有效期
存储变量时 设置变量的有效期 px(毫秒) ex (秒)
192.168.90.64:6379> set【赛特】 name jam ex 10 #变量10秒过期OK192.168.90.64:6379> set【赛特】 class nsd px 10 #变量10毫秒过期OK192.168.90.64:6379>
# NX 不覆盖赋值192.168.90.64:6379> set【赛特】 name xiaohong NX(nil)192.168.90.64:6379> get【脚(白话)特】 name"jam"
# XX 覆盖赋值192.168.90.64:6379> set【赛特】 name yaya XXOK192.168.90.64:6379> get【脚(白话)特】 name"yaya"192.168.90.64:6379>set【赛特】 命令完整格式演示
set 名称 值 有效期类型 有效时间 是否覆盖 set gender girl ex 20 NX
192.168.90.64:6379> set【赛特】 gender girl ex 20 NXOK4.6 数字增减操作
incr【因kuì儿】 递增数字
- 递增数字:字符串类型可以存储任何形式的字符串,当存储的字符串是整数形式时,
Redis【瑞迪斯】 提供了一个实用的命令 incr【因kuì儿】,其作用是让当前键值递增,并返回递增后的值。
当要操作的键不存在时会默认键值为0,所以第一次递增后的结果是1。
# 创建变量192.168.90.64:6379> set【赛特】 num 1192.168.90.64:6379> incr【因kuì儿】 num #+1(integer) 2192.168.90.64:6379> incr【因kuì儿】 num #+1(integer) 3192.168.90.64:6379> get【脚(白话)特】 num"3"
# 复数递增数字 incrby192.168.90.64:6379> incrby【因kuì儿 by】 num 2 #+2(integer) 5192.168.90.64:6379> incrby【因kuì儿 by】 num 3 #+3(integer) 8decr【迪kuì儿】 递减数字
- 增加指定的整数
- 递减数字192.168.90.64:6379> decr【迪kuì儿】 num #-1(integer) 7
# 复数递减数字 decrby192.168.90.64:6379> decrby num 3 #(integer) 4append【额 篇的】 尾部追加值
- 向尾部追加值
append【额 篇的】通常指追加操作。在文件处理方面,可将数据添加到已有文件的末尾,而不是覆盖原内容。
# 创建变量hi192.168.90.64:6379> set【赛特】 hi HelloOK
# 因为字符串包含空格,需要使用引号192.168.90.64:6379> append【额 篇的】 hi " World"(integer) 11 # 返回值为hi的总长度
192.168.90.64:6379> get【脚(白话)特】 hi"Hello World"4.7 字符串处理
strlen【斯拽轮】 获取字符串长度
- 获取字符串长度
strlen【斯拽轮】是用于获取存储在指定键的字符串值的长度的命令
192.168.90.64:6379> strlen【斯拽轮】 hi(integer) 11- 中文字符返回字节数192.168.90.64:6379> set【赛特】 name 张三OK192.168.90.64:6379> strlen【斯拽轮】 name(integer) 6 # UTF-8编码的中文,由于“张”和“三”两个字的UTF-8编码的长度都是3,所以此例中会返回6。getrange 获取变量部分数据
getrange【脚(白话) cùn局】命令用于获取存储在指定键的字符串值的子字符串。它的核心用途是按指定的起始和结束位置提取字符串的一部分。
# 创建变量192.168.90.64:6379> set【赛特】 zfc ABCEFOK
# 输出变量值192.168.90.64:6379> get zfc"ABCEF"
# 输出第1个到第2个字符192.168.90.64:6379> getrange【脚(白话) cùn局】 zfc 0 1"AB"
# 输出第3个到第5个字符192.168.90.64:6379> getrange【脚(白话) cùn局】 zfc 2 4"CEF"
# 输出倒数第2个到第1个字符192.168.90.64:6379> getrange【脚(白话) cùn局】 zfc -2 -1"EF"192.168.90.64:6379>五、Key【kì】的操作
当前任务环节

5.1 keys 列出所有的key【kì】
192.168.90.64:6379> keys *1) "age"2) "classs"3) "name"4) "school【斯故】"
#keys 使用统配符查看变量, * 匹配所有变量名, ? 一个字符
# 变量名是3个字符192.168.90.64:6379> keys ???1) "age"
# 变量名是a 开头的192.168.90.64:6379> keys a*1) "age"
# 查看指定变量是否存在192.168.90.64:6379> keys gender(empty list or set) # 说明变量没有定义
192.168.90.64:6379> keys name1) "name"5.2 select【涩莱克特】 选择数据库
(redis【瑞迪斯】总共有15个库,从0到15)
# select【涩莱克特】 切换库 默认库编号 0-15
# 切换到 1号库里192.168.90.64:6379> select【涩莱克特】 1OK
# 查看数据没有数据192.168.90.64:6379[1]> keys *(empty list or set)192.168.90.64:6379[1]>192.168.90.64:6379[1]> select【涩莱克特】 0OK192.168.90.64:6379> select【涩莱克特】 16(error) ERR DB index is out of range
# move 命令 移动变量到其他库里192.168.90.64:6379> keys *1) "age"2) "classs"3) "name"4) "school【斯故】"5.3 move 把某个key【kì】移动到某个库中
move 命令 移动变量到其他库里
192.168.90.64:6379> keys *1) "age"2) "classs"3) "name"4) "school【斯故】"
# 把age 变量移动到1 号库里192.168.90.64:6379> move age 1(integer) 1192.168.90.64:6379> keys *1) "classs"2) "name"3) "school【斯故】"192.168.90.64:6379> select【涩莱克特】 1OK192.168.90.64:6379[1]> keys *1) "age"5.4 exists【伊贼谁斯】 判断一个key【kì】是否存在
#exists【伊贼谁斯】 检查变量是否存储 返回值1 变量存储 返回值是0 变量不存在192.168.90.64:6379[1]> select【涩莱克特】 0OK192.168.90.64:6379> EXISTS【伊贼谁斯】 name # 检查name变量是否存在(integer) 1192.168.90.64:6379> get【脚(白话)特】 name"plj"192.168.90.64:6379> set【赛特】 name bobOK192.168.90.64:6379> get【脚(白话)特】 name"bob"5.5 key【kì】的过期时间
expire【ī 斯 拜尔】 设置一个key【kì】的过期时间
ttl 查看一个剩余的过期时间
#EXPIRE【ī 斯 拜尔】 命令设置变量的过期时间 不设置变量永不过期#ttl 检查变量可以在内存里存多久192.168.90.64:6379> set【赛特】 sex girlOK192.168.90.64:6379> ttl sex(integer) -1 #表示永不过期
192.168.90.64:6379> EXPIRE【ī 斯 拜尔】 sex 15 #设置过期时间15 秒(integer) 1
192.168.90.64:6379> keys sex1) "sex"
192.168.90.64:6379> ttl sex(integer) 8 #还剩下8秒时间过期
192.168.90.64:6379> ttl sex(integer) -2 #表示已经过期被删除
192.168.90.64:6379> keys sex(empty list or set)衍生命令(高频扩展)
Redis针对过期时间提供了更灵活的衍生命令,补充EXPIRE的不足:
| 命令 | 功能 | 示例 |
|---|---|---|
PEXPIRE | 设置毫秒级过期时间(更高精度) | PEXPIRE user:session:100 1800000(30分钟) |
EXPIREAT | 设置Key在指定Unix时间戳(秒)过期 | EXPIREAT order:1001 1716643200(2024-05-26 00:00:00) |
PEXPIREAT | 设置Key在指定Unix时间戳(毫秒)过期 | PEXPIREAT order:1001 1716643200000 |
TTL | 查看Key剩余过期时间(秒,-1=永不过期,-2=已删除) | TTL user:session:100 |
PTTL | 查看Key剩余过期时间(毫秒) | PTTL user:session:100 |
PERSIST | 移除Key的过期时间(设为永不过期) | PERSIST user:session:100 |
5.6 type【泰 普】 查看某个key【kì】是属于哪个数据类型
#type【泰 普】 命令检查变量存储数据的类型#使用set【赛特】 mset命令存储的数据都字符类型。#数据的类型不同 管理的命令也不同#明天讲数据类型。
192.168.90.64:6379> set【赛特】 x 99OK192.168.90.64:6379> mset y 108OK192.168.90.64:6379> type【泰 普】 xstring192.168.90.64:6379> type【泰 普】 ystring5.7 del 删除一个key【kì】
#del 删除内存里的变量192.168.90.64:6379> keys *1) "y"2) "tea"3) "name"4) "school【斯故】"5) "x"6) "classs"192.168.90.64:6379> del tea y school【斯故】(integer) 3192.168.90.64:6379> keys *1) "name"2) "x"3) "classs"5.8 flushdb【福 辣 徐 db】 删除本库的所有的key【kì】
#flushdb【福 辣 徐 db】 删除当前所在库的所有数据192.168.90.64:6379> keys *1) "name"2) "x"3) "classs"192.168.90.64:6379> flushdb【福 辣 徐 db】OK192.168.90.64:6379> keys *(empty list or set)192.168.90.64:6379> SELECT【涩莱克特】 1OK192.168.90.64:6379[1]> keys *1) "age"5.9 flushall【福 辣 徐 ò】 删除所有库的key【kì】
192.168.90.64:6379[1]> flushall【福 辣 徐 ò】 #删除内存里的所有内存里所有数据 (慎用)六、列表类型(list【lì斯特】类型)
当前任务环节

6.1 应用场景
Redis【瑞迪斯】 列表类型是一种简单的数据结构,可用来实现队列、栈和日志记录等功能。其应用场景广泛,以下是一些常见的场景:
- 消息队列:适合实现生产者 - 消费者模式。生产者使用LPUSH【L 普斯】 命令将消息从列表左端插入,消费者使用BRPOP或RPOP【R 扑】命令从右端取出消息处理。如在微服务架构里,一个服务可将任务作为消息放入列表,另一个服务作为消费者取出任务执行。还能用于任务队列,像电商网站中,用户下单后将订单处理任务放入列表,后台工作进程取出任务进行库存更新、订单确认等操作,避免用户等待,提升体验。
- 排行榜:可用于时间序列排行榜,如在游戏里将玩家得分和时间戳作为元素放入列表,对列表排序可得不同时间段的玩家排行榜。也能实现动态排行榜,在直播平台中,观众送礼物增加主播人气值,人气值变化实时反映在排行榜上,通过快速插入新元素和删除旧元素实现榜单实时更新。
- 历史记录存储:可存储用户操作历史,如文档编辑系统中,用LPUSH【L 普斯】 命令将用户每次编辑操作记录插入列表,用LRANGE【L 轮局】 命令获取一定范围的历史记录,方便用户查看历史版本或撤销操作。还能用于系统日志记录,Web应用中,将用户登录日志、请求日志等存储在列表,便于进行日志查询和分析,故障排查时可快速获取相关日志信息。
- 栈和队列数据结构的实现:可作为栈使用,用LPUSH【L 普斯】 命令将元素插入列表头部,用LPOP【L 扑】 命令从头部弹出元素,实现后进先出的栈结构,用于一些算法实现。也能当作队列,用LPUSH【L 普斯】 命令将元素插入头部,用RPOP【R 扑】 命令从尾部弹出元素,实现先进先出的队列结构,如任务调度系统中,将任务按提交顺序放入队列,工作进程依次取出执行。
- 社交平台相关场景:如微信朋友圈点赞,按点赞顺序显示点赞好友信息,取消点赞时移除对应好友信息;Twitter、微博等社交平台中,个人用户的关注列表按关注顺序展示,粉丝列表将最近关注的粉丝列在前面。
- 待办事项与购物车:可以作为待办事项列表使用,用户添加待办事项时用LPUSH【L 普斯】 或RPUSH【R 普斯】插入列表,完成事项后用LPOP【L 扑】 或RPOP【R 扑】 移除。购物车也可使用列表实现,商品添加到购物车时插入列表,结算或移除商品时从列表移除 。
- 秒杀抢购:将商品ID作为key【kì】,商品数目作为value【挖柳】 存储在列表中,在秒杀场景中使用。
- 实时在线用户管理:可用于存储实时在线用户的列表,实现实时更新和查询在线用户信息。
- 日志记录:在Web应用中,将用户请求的URL和请求时间push到列表,并设置列表长度为一定值,查看日志时通过lrange【L 轮局】 命令获取之前请求过的URL和请求时间。
6.2 向列表左边增加元素
lpush【L 普斯】向列表左边增加元素
LPUSH【L 普斯】 命令用来向列表左边增加元素,返回值表示增加元素后列表的长度
lpush【L 普斯】是“left push”的缩写,用于将一个或多个值插入到列表的头部(左侧)
命令格式为LPUSH key value1 value2...
# 创建变量192.168.90.64:6379> lpush【L 普斯】 letter A B C(integer) 3
# 查看类型192.168.90.64:6379> type【泰 普】 letterlist【lì斯特】
# 头部追加元素192.168.90.64:6379> lpush【L 普斯】 letter d e(integer) 5lrange【L 轮局】取出列表所有元素
lrange【L 轮局】用于获取列表指定范围内的元素。它能按索引范围提取列表中的部分或全部元素。
命令格式为LRANGE key 开始 结束
# 起始下标为0,结束下标为-1192.168.90.64:6379> lrange【L 轮局】 letter 0 -11) "e"2) "d"3) "C"4) "B"5) "A"llen【L 轮】统计元素个数
llen【L 轮】是用于获取列表长度的命令。它返回存储在指定键的列表中的元素数量。
格式:有一个名为my_list的列表,执行LLEN my_list命令,就能知道my_list中有多少个元素。
192.168.90.64:6379> llen【L 轮】 letter(integer) 56.3 lindex索引元素
lindex【L 因戴克斯】命令用于获取列表中指定索引位置的元素。
通过下标输出单个元素 第1个元素下标用0表示 第2个元素下标用1表示
最后一个元素下标用-1表示
192.168.90.64:6379> lindex【L 因戴克斯】 letter 0"e"192.168.90.64:6379> lindex【L 因戴克斯】 letter 2"C"
# 最后1个192.168.90.64:6379> lindex【L 因戴克斯】 letter -1"A"
# 倒数第2个192.168.90.64:6379> lindex【L 因戴克斯】 letter -2"B"6.4 lset【L 赛特】修改元素
lset【L 赛特】用于设置列表中指定索引位置的元素值。
# 修改前查看192.168.90.64:6379> lrange【L 轮局】 letter 0 -11) "e"2) "d"3) "C"4) "B"5) "A"
# 修改第1元素192.168.90.64:6379> lset letter 0 EOK
# 修改最后1个元素192.168.90.64:6379> lset letter -1 aOK
# 修改后查看192.168.90.64:6379> lrange【L 轮局】 letter 0 -11) "E"2) "d"3) "C"4) "B"5) "a"6.5 弹出元素(删除元素)
lpop【L 扑】是“left pop”的缩写,用于从列表的头部(左侧)移除并返回一个元素。
rpop【R 扑】即“right pop”的缩写,用于从列表的尾部(右侧)移除并返回一个元素。
192.168.90.64:6379> lrange【L 轮局】 letter 0 -1 #修改前查看1) "E"2) "d"3) "C"4) "B"5) "a"192.168.90.64:6379> lpop【L 扑】 letter #弹出头部元素"E"192.168.90.64:6379> rpop【R 扑】 letter #弹出尾部元素"a"192.168.90.64:6379> lrange【L 轮局】 letter 0 -1 #修改后查看1) "d"2) "C"3) "B"6.6 尾部追加元素
rpush是“right push”的缩写,用于将一个或多个值插入到列表的尾部(右侧) 。
192.168.90.64:6379> rpush【R 普斯】 letter e f #尾部追加元素(integer) 5192.168.90.64:6379> lrange【L 轮局】 letter 0 -1 #追加后查看1) "d"2) "C"3) "B"4) "e"5) "f"6.7 插入元素
linsert【L 因涩特】用于在列表指定元素的前或后插入新元素。
before【B fò】表示在……之前。
after【啊夫特】 常用于表达在……之后。
192.168.90.64:6379> lrange【L 轮局】 letter 0 -1 #插入前查看1) "d"2) "C"3) "B"4) "e"5) "f"192.168.90.64:6379>192.168.90.64:6379> linsert【L 因涩特】 letter before【B fò】 C C2 #值C前插入C2(integer) 6192.168.90.64:6379> lrange【L 轮局】 letter 0 -1 #插入后查看1) "d"2) "C2"3) "C"4) "B"5) "e"6) "f"192.168.90.64:6379>192.168.90.64:6379> linsert【L 因涩特】 letter after【啊夫特】 C C3 #值C后插入C3(integer) 7192.168.90.64:6379> lrange【L 轮局】 letter 0 -1 #插入后查看1) "d"2) "C2"3) "C"4) "C3"5) "B"6) "e"7) "f"七、散列类型(hash【哈希】类型)
当前任务环节

7.1 应用场景
Redis【瑞迪斯】 散列类型是字符串字段和字符串值之间的映射,类似 Python 字典或 Java 的 HashMap,适合存储对象,且可像数据库更新记录一样只修改特定字段。其具体应用场景如下:
- 用户信息存储:每个用户对应一个 Hash【哈希】,以用户 ID 为键名,使用字段表示用户的属性,如姓名、年龄、生日等,而字段值则存储属性值。相比用普通的 key【kì】/value【挖柳】 结构存储,避免了序列化/反序列化的开销,且在修改其中一项信息时,无需把整个对象取回,也无需引入复杂的并发保护机制。
- 商品属性存储:可用于存储商品的多维度属性,如价格、库存、描述等。通过散列类型,能方便地对商品的各个属性进行单独的查询、修改和更新操作,提高数据处理的效率和灵活性。
- 配置管理:适用于动态更新配置字段的场景,无需反序列化整个对象。系统的配置信息可存储在散列中,当配置发生变化时,只需更新相应的字段即可,保证系统的配置信息能实时生效,且操作简单高效。
- 购物车:以用户 ID 为 key【kì】,商品 ID 为 field,商品数量为 value【挖柳】。用户向购物车中添加商品时,可通过操作散列类型来记录商品信息和数量;修改商品数量或删除商品时,也能方便地对散列中的对应字段进行更新或删除操作。
- 文章内容存储:对于文章的各种属性,如标题、作者、发布时间、内容摘要等,可以使用散列类型进行存储,以文章 ID 作为键名,各个属性作为字段和字段值,便于对文章信息进行管理和查询。
7.2 存储数据和获取数据
赋值与取值
hset【h 赛特】用于在哈希表(hash)中设置一个字段(field)的值。
hmset【hm 赛特】用于同时设置哈希表中的多个字段值。
hget【h 脚(白话)特】用于从哈希表中获取指定字段的值。
hmget【hm 脚(白话)特】用于从哈希表中获取一个或多个指定字段的值。
192.168.90.64:6379> hset【h 赛特】 user1 name bob #创建变量(integer) 1192.168.90.64:6379> type【泰 普】 user1 #查看类型hash192.168.90.64:6379>192.168.90.64:6379> hset【h 赛特】 user1 gender man #赋新值(integer) 1192.168.90.64:6379> hget【h 脚(白话)特】 user1 name #查看name列的值设置多个字段
192.168.90.64:6379> hmset【hm 赛特】 user1 email bob@qcjy.cn phone 13412345678OK192.168.90.64:6379> hmget【hm 脚(白话)特】 user1 email phone1) "bob@qcjy.cn"2) "13412345678"获取所有列名及对应的值
hgetall【h 脚(白话)特 ò】用于获取哈希表中所有的字段和值。
192.168.90.64:6379> hgetall【h 脚(白话)特 ò】 user11) "name"2) "bob"3) "gender"4) "male"5) "email"6) "bob@qcjy.cn"7) "phone"8) "13412345678"7.3 其他操作
hdel删除列
hdel【h 戴尔】用于删除哈希表中的一个或多个字段。
192.168.90.64:6379> hdel【h 戴尔】 user1 age(integer) 1只获取列名
hkeys【h kì s】用于获取哈希表中的所有字段名。
192.168.90.64:6379> hkeys【h kì s】 user11) "name"2) "gender"3) "email"4) "phone"5) "address"只获取值
hvals【h 瓦尔兹】命令用于获取哈希表中所有字段的值。
192.168.90.64:6379> hvals【h 瓦尔兹】 user11) "bob"2) "male"3) "bob@qcjy.cn"4) "13412345678"5) "beijing"获得列数量
hlen【h 轮】用于获取哈希表中字段的数量。
192.168.90.64:6379> hlen【h 轮】 user1(integer) 5八、集合类型
当前任务环节

8.1 应用场景
Redis【瑞迪斯】 集合类型是一种不允许重复元素的非线性结构,可用于存储和管理元素集合,其应用场景广泛,以下是一些常见的场景:
- 用户管理:在社交网络中可存储用户特征和记录,轻松检索用户 ID、用户名等信息;也能用于会员管理,保护和检索会员记录。
- 网站流量监控:将客户端 IP 等唯一标识添加到 Redis【瑞迪斯】 集合中,可有效跟踪网站流量,检测重复访客或恶意行为。
- 奖励管理:可以跟踪和管理奖励,方便对奖励信息进行添加、查询等操作。
- 排行榜:在搜索引擎、电影、游戏等场景中,可维护实时热门排行榜榜单。如在游戏里,可存储玩家得分或排名信息,通过集合操作实现排行榜的更新和查询。
- 标签系统:可用于存储每篇文章或商品的标签,方便根据标签进行分类和搜索。例如新闻网站可以为每篇新闻文章添加标签,用户可以根据标签快速找到感兴趣的文章。
- 社交应用:可存储用户的好友列表,通过求交集来找出共同的好友,实现共同兴趣的推荐;还能存储关注者信息,进行关注和取消关注的操作。
- 唯一性检查:集合中的元素具有唯一性,可用于检查元素是否已存在。如在注册系统中,检查用户名是否已被使用。
- 抽奖活动:将参与抽奖的用户 ID 存储在集合中,通过随机获取集合中的元素来实现抽奖功能,保证每个用户只有一次中奖机会。
- 点赞和共同关注:存储点赞用户的 ID 集合,判断某个用户是否点赞;也可通过集合操作找出多个用户的共同关注对象。
8.2 无序集合
无序集合中的每个元素都是不同的,且没有顺序
8.2.1 创建/追加/删除/查看
sadd用于向集合(set)中添加一个或多个成员。集合是一个无序且唯一的字符串集合。命令格式为SADD key member1 member2… 。
例如,执行SADD myset “apple” “banana”,就会将 “apple” 和 “banana” 添加到名为myset的集合中。当需要维护一个唯一值的集合,比如用户标签集合,使用sadd添加标签,可保证标签的唯一性。
srem【s 轮姆】命令用于移除集合中的一个或多个成员。集合是无序且元素唯一的结构。比如有集合my_set,执行命令SREM【s 轮姆】 my_set value1 value2,就会从my_set集合中移除value1和value2。这在管理集合数据,像用户兴趣标签集合,需要删除某些用户不再感兴趣的标签时非常有用。
smembers【s 门伯兹】用于获取集合中的所有成员。命令格式为SMEMBERS key。例如,执行SMEMBERS myset,会返回名为myset集合中的所有元素。当你需要查看集合内的所有数据,比如查看用户拥有的所有标签时,smembers就十分有用。
192.168.90.64:6379> sadd mylike film muisc game #创建(integer) 3192.168.90.64:6379> type【泰 普】 mylike #查看数据类型set192.168.90.64:6379> sadd mylike sleep game it #追加,自动删除重复的值(integer) 2192.168.90.64:6379> srem【s 轮姆】 mylike sleep game #删除成员(integer) 2192.168.90.64:6379> smembers【s 门伯兹】 mylike #查看成员1) "film"2) "it"3) "muisc"8.2.2 判断元素是否在集合中
sismember【sis 门伯】是一个用于判断指定成员是否存在于集合中的命令 。其命令格式为SISMEMBER key member。假设你有一个名为fruits的集合,执行SISMEMBER fruits "banana",若banana存在于fruits集合,该命令返回1;若不存在,则返回0 。
192.168.90.64:6379> sismember【sis 门伯】 mylike game #输出0表示不存在(integer) 0192.168.90.64:6379> sismember【sis 门伯】 mylike music #输出1表示存在(integer) 18.2.2.1输出成员个数
scard【s 卡德】用于获取集合中成员的数量。命令格式为SCARD key。例如,对于名为my_set的集合,执行SCARD my_set,就会返回该集合包含的元素个数。
192.168.90.64:6379> scard【s 卡德】 mylike(integer) 3192.168.90.64:6379>8.2.3 集合运算
192.168.90.64:6379> smembers mylike1) "film"2) "it"3) "muisc"192.168.90.64:6379> sadd helike film music game sleep(integer) 4192.168.90.64:6379>合集 sunion【s U凝】
sunion【s U凝】用于返回一个集合的并集,即多个集合中所有不同的元素组成的集合。命令格式为SUNION key1 key2...。例如,有集合set1包含元素a、b,集合set2包含元素b、c,执行SUNION set1 set2会返回包含a、b、c的集合。
#合集 重复的只显示一次192.168.90.64:6379> sunion【s U凝】 mylike helike1) "game"2) "it"3) "muisc"4) "film"5) "sleep"6) "music"192.168.90.64:6379>交集sinter【s 因特尔】
sinter【s 因特尔】用于返回多个集合的交集,即所有给定集合中都存在的元素组成的集合。命令格式为SINTER key1 key2... 。例如,集合set1包含a、b、c,集合set2包含b、c、d,执行SINTER set1 set2,返回的集合将包含b、c
#交集192.168.90.64:6379> sinter【s 因特尔】 mylike helike1) "film"192.168.90.64:6379>差集sdiff【s 迪夫】
sdiff【s 迪夫】用于返回给定集合之间的差集。命令格式为SDIFF key1 key2... 。以两个集合为例,sdiff会返回在key1集合中,但不在key2及后续集合中的所有元素。比如集合set1包含a、b、c,集合set2包含b、c,执行SDIFF set1 set2,返回的集合将只包含a 。
#差集: 用第1列的变量和第2列的变量比192.168.90.64:6379> sdiff【s 迪夫】 mylike helike1) "it"2) "muisc"192.168.90.64:6379> sdiff【s 迪夫】 helike mylike1) "game"2) "sleep"3) "music"192.168.90.64:6379>8.2.4 随机获得集合中的元素
srandmember【s 轮 门伯】用于从集合中随机返回一个或多个成员。命令格式为SRANDMEMBER key [count]。若不指定count,则随机返回一个成员;若指定count,且为正数,会返回指定数量不重复的成员(若集合元素不足,返回实际数量);若count为负数,会返回指定数量可能重复的成员。
# 在集合helike中随机取出两个不同元素。192.168.90.64:6379> srandmember【s 轮 门伯】 helike 21) "sleep"2) "music"192.168.90.64:6379> srandmember【s 轮 门伯】 helike 21) "game"2) "music"192.168.90.64:6379># 在集合helike中随机取出两个有可能相同元素。192.168.90.64:6379> srandmember【s 轮 门伯】 helike -21) "film"2) "music"192.168.90.64:6379> srandmember【s 轮 门伯】 helike -21) "music"2) "music"8.2.5 集合中随机弹出一个元素
spop【s 扑】用于从集合中随机移除并返回一个成员。命令格式为SPOP key。例如,对于名为my_set的集合,执行SPOP my_set,会从my_set集合里随机挑选一个元素并删除它,同时返回该元素。
192.168.90.64:6379> spop【s 扑】 helike #第1次弹出"music"192.168.90.64:6379> spop【s 扑】 helike #第2次弹出"game"192.168.90.64:6379> smembers【s 门伯兹】 helike #查看1) "film"2) "sleep"8.3 有序集合
8.3.1 zadd命令的返回值是新加入到集合中的元素个数
zadd用于向有序集合(Sorted Set)中添加一个或多个成员,同时为每个成员关联一个分数(score),有序集合会根据分数对成员进行排序。命令格式为ZADD key score1 member1 [score2 member2 ...] 。例如,执行ZADD myzset 10 "apple" 20 "banana",就会将“apple”和“banana”添加到名为myzset的有序集合中,“apple”的分数是10,“banana”的分数是20 。
zcard用于获取有序集合中的成员数量。命令格式为ZCARD key。例如,对于名为myzset的有序集合,执行ZCARD myzset,会返回myzset集合中的元素个数。
zrange用于返回有序集合中指定区间内的成员。有序集合成员按分数值递增(从小到大)顺序排列。命令格式为ZRANGE key start stop [WITHSCORES]。start和stop是元素的索引值,索引从0开始,负数表示从集合尾部开始计数, -1 代表最后一个元素。例如,执行ZRANGE myzset 0 2 WITHSCORES,会返回名为myzset的有序集合中索引0到2的成员及其分数
withscores是一个可选参数。当使用它时,命令在返回有序集合成员的同时,还会返回每个成员对应的分数。例如ZRANGE myzset 0 -1 WITHSCORES,会返回myzset有序集合中所有成员及其对应的分数。
192.168.90.64:6379> zadd scores 88 tom 90 jerry 75 bob 92 alice #创建变量(integer) 4192.168.90.64:6379> type【泰 普】 scores #查看类型zset192.168.90.64:6379> zcard【z 卡德】 scores #统计成员个数(integer) 4192.168.90.64:6379> zrange【z 轮局】 scores 0 -1 #输出成员名称1) "bob"2) "tom"3) "jerry"4) "alice"192.168.90.64:6379> zrange【z 轮局】 scores 0 -1 withscores【维s 科s】 #输出成员名称及对应的值1) "bob"2) "75"3) "tom"4) "88"5) "jerry"6) "90"7) "alice"8) "92"8.3.2 获得某个成员的值
192.168.90.64:6379> zscore【z s科】 scores tom"88"8.3.3 获得指定分数范围的元素
zrangebyscore用于返回有序集合中指定分数区间内的成员。命令格式为ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count] 。min和max是分数范围,比如执行ZRANGEBYSCORE myzset 80 100 WITHSCORES,会返回名为myzset的有序集合中分数在80(含)到100(含)之间的成员及其分数。WITHSCORES可选,用于显示成员对应的分数,LIMIT用于指定返回结果的偏移量和数量。
192.168.90.64:6379> zrangebyscore【z 轮局 拜 s科】 scores 80 90 WITHSCORES【维s 科s】1) "jerry"2) "85"3) "tom"4) "88"8.3.4 增加某个元素的分数
zincrby【z 因kuì儿 拜】用于为有序集合中的成员增加指定的分数。命令格式为ZINCRBY key increment member 。例如,执行ZINCRBY myzset 5 "player1",会将有序集合myzset中的成员“player1”的分数增加5 。
192.168.90.64:6379> zincrby【z 因kuì儿 拜】 scores 3 bob"78"192.168.90.64:6379> zscore【z s科】 scores bob"78"8.3.5 获得指定分数范围内的元素个数
zcount【z kàn特】用于统计有序集合中指定分数区间内成员的数量。命令格式为ZCOUNT key min max。比如执行ZCOUNT myzset 60 80,就会返回名为myzset的有序集合中分数在60(含)到80(含)之间的成员数量。
192.168.90.64:6379> zcount【z kàn特】 scores 80 90(integer) 28.3.6 删除元素
zrem【z 轮姆】用于从有序集合中移除一个或多个成员。命令格式为ZREM key member [member ...] 。例如,执行ZREM myzset "member1" "member2",会从名为myzset的有序集合中移除“member1”和“member2” 。
192.168.90.64:6379> zrem【z 轮姆】 scores bob(integer) 18.3.7 获得元素的排名
zrank【z 软克】用于获取有序集合中指定成员的排名。排名从0开始,是按分数从小到大排列的索引值。命令格式为ZRANK key member。例如,对于有序集合myzset,执行ZRANK myzset "member1",会返回“member1”在myzset集合中的排名。
zrevrank【z 瑞乌 软克】与zrank【z 软克】类似,但它是获取有序集合中指定成员按分数从大到小排列的排名。命令格式为ZREVRANK key member。例如,在名为myzset的有序集合里执行ZREVRANK myzset "member1",会返回“member1”在myzset集合中按分数降序排列的排名。
192.168.90.64:6379> zrank【z 软克】 scores tom # 获取tom的排名(integer) 1 # 升序排列,从0开始计数
192.168.90.64:6379> zrevrank【z 瑞乌 软克】 scores alice # 获取alice的排名(integer) 0 # 降序排列,从0开始计数九、作业
1 选择题
- Redis 集合类型中,以下哪个命令用于判断元素是否在集合中? B A. sunion B. sismember C. sinter D. sdiff
- 若要在 Redis 列表类型中从尾部追加元素,应使用以下哪个命令?C A. LPUSH B. RPOP C. RPUSH D. LPOP
- Redis 散列类型适合存储以下哪种数据? C A. 单一的字符串 B. 有序的元素列表 C. 具有多个属性的对象 D. 不允许重复的无序元素
2 填空题
- Redis 字符串类型中,使用__incr__命令可以让存储的整数值递增。
- 在 Redis 列表类型中,用__lpop__命令可以从列表头部弹出元素。
- Redis 集合类型中,用于获取两个集合交集的命令是__sinter__。
3 简答题
-
简述 Redis 散列类型在存储用户信息方面相较于普通 key/value 结构的优势。 答: 相比用普通的 key /value 结构存储, 散列类型存储每个用户对应一个 Hash,以用户 ID 为键名,使用字段表示用户的属性,如姓名、年龄、生日等,而字段值则存储属性值。避免了序列化/反序列化的开销,且在修改其中一项信息时,无需把整个对象取回,也无需引入复杂的并发保护机制。
-
请说明 Redis 列表类型可以实现哪些数据结构,以及对应的命令操作。 答:
1. 队列: 127.0.0.1:6379> lpush test3 1 2 3 4 #在列队头部插入元素 (integer) 7 127.0.0.1:6379> rpush test3 1 2 3 4 #在列队尾部插入元素 (integer) 11 127.0.0.1:6379> lpop test3 #移除并返回队列的第一个元素 "4" 127.0.0.1:6379> rpop test3 #移除并返回队列的最后一个元素 "4"
2. 栈:
127.0.0.1:6379> lpush test3 1 2 3 4 #列表左侧(头部) 插入元素 (integer) 4 127.0.0.1:6379> lpop test3 #列表左侧(头部) 移除并获取元素 "4"- 列举 Redis 集合类型的三个常见应用场景。 答: 社交应用 唯一性检查 抽奖活动
4 操作题
- 假设你已经连接到 Redis 服务,现在要创建一个散列类型的数据,键名为“product1”,包含字段“name”值为“手机”,“price”值为“3000”,“stock”值为“50”,请写出对应的 Redis 命令。
127.0.0.1:6379> hmset product1 name 手机 price 3000 stock 50OK127.0.0.1:6379> hmget product1 name price stock1) "\xe6\x89\x8b\xe6\x9c\xba"2) "3000"3) "50"127.0.0.1:6379>- 有一个 Redis 列表类型的数据“history_list”,请写出命令将元素“操作 1”插入到列表头部,并从列表尾部弹出一个元素。
127.0.0.1:6379> lpush history_list A B C(integer) 3127.0.0.1:6379> lrange history_list 0 -11) "C"2) "B"3) "A"127.0.0.1:6379> lpush history_list 操作1(integer) 4127.0.0.1:6379> lrange history_list 0 -11) "\xe6\x93\x8d\xe4\xbd\x9c1"2) "C"3) "B"4) "A"127.0.0.1:6379> rpop history_list"A"127.0.0.1:6379> lrange history_list 0 -11) "\xe6\x93\x8d\xe4\xbd\x9c1"2) "C"3) "B"127.0.0.1:6379>- 现有两个 Redis 集合“set1”包含元素“a”“b”“c”,“set2”包含元素“b”“c”“d”,请写出命令获取它们的并集、交集和差集。
127.0.0.1:6379> sadd set1 a b c(integer) 3127.0.0.1:6379> sadd set2 b c d(integer) 3127.0.0.1:6379> sunion set1 set2 #并集1) "b"2) "a"3) "d"4) "c"127.0.0.1:6379> sinter set1 set2 #交集1) "b"2) "c"127.0.0.1:6379> sdiff set1 set2 #差集1) "a"127.0.0.1:6379>