[redis] 10 种数据结构详解
2022/2/11 2:13:03
本文主要是介绍[redis] 10 种数据结构详解,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
[redis] 10 种数据结构详解
简介
5种常见数据结构
- string: 最常见的 string key value
- list: 双向链表
- set: 集合-
- zset: 有序集合
- hash: 类似 Java HashMap 和 golang 的 map 有 2 级索引
原语------ | 介绍 | 常见场景 |
---|---|---|
string | string key/value 最常见的数据类型 | 最常用缓存; 分布式锁; 储存日志; id生成器; 计数器; 限速限流; |
hash | hashmap(成员少时数组, 多时升级为hashmap) | 更加细粒度缓存对象 |
list | 实现是双向链表或者说一个队列 | 消息队列; 待办事项; |
set | 不重复的列表, 自动去重, 类似数据集合概念(内部实现是一个 value 为 null 的 hashmap) | 唯一计数器; 打标签; 点赞;投票; 社交关系; 推荐商品; |
zset | 有序的set, 提供额外的 score 参数来排序(内部实现是 hashmap 和 跳表) | 排行榜; 推荐商品; 自动补全(字典排序) |
5种其他数据结构
- hypperLoglog: 基数统计
- bitmap: 位图(布隆过滤器)
- geo: 地理位置坐标
- pub/sub: 发布订阅
- stream: 流(主要用于消息队列, 解决 pub/sub 发布订阅没有消息持久化的问题)
原语 | 介绍 | 场景 |
---|---|---|
hpperLogLog | 唯一计数器(12k就能计数2^64个成员, 计数估计算法误差0.81%) | 网站访客量ip; 检测垃圾信息;每周/月度/年度计数器 |
bitmap | bit数组, 用户可以通过偏移量(offset)对一个或者多个二进制进行位操作 | 布隆过滤器 |
geo | 地理坐标, 通过坐标距离计算范围查找 | 记录坐标; 附近的用户; |
pub/sub | 发布订阅, 消息队列(不能持久化) | 发布队列 |
stream | 消息队列(解决 list, zset 不能范围操作, pub/sub发布订阅不能持久化的问题) | 消息队列 |
string key value
string 是 redis 最常用最基本的数据结构, 不仅可以储存 string, 数字, 也可以是图片, 音频等更复杂的二进制数据
1. 储存结构
2.原语
SET key value[EX seconds|PX millisecods|EXAT timestamp|PXAT milliseconds-timestamp|KEEPTTL] [NX|EX] [GET]
原语 | 介绍 |
---|---|
SET key value | 设置key value 值 |
GET key | 获取 key value值 |
DEL key | 删除key value值(通用的方法能删除其他数据结构) |
SET key value NX | 设置值, key 不存在才能设置成功 |
SETNX key value | 设置值, key 不存在才能设置成功(同上) |
SET key value XX | 设置值, key 存在才能设置成功 |
SETXX key value | 设置值, key 存在才能设置成功(同上) |
SET key value EX seconds | 设置值和过期时间, 单位秒 |
SET key value PX milliseconds | 设置值和过期时间, 单位毫秒 |
EXPIRE key seconds | 设置过期时间, 单位秒 |
INCR key | 递增 1 , 如果 value 不是数字或者越界会报错 |
DNCR key | 递减少 1, 如果 value 不是数字或者越界会报错 |
INCRBY key integer | 递增 integer |
DNCRBY key integer | 递减 integer |
GETSET key value | 设置值并返回旧值 |
GETSET key value | SET并GET旧的值 |
MGET key [key...] | 批量 GET 一般搭配 keys 批量获取键来使用 |
STRLEN key | 获取 value 长度 |
GETBIT key offset | 得到 value 的 offset 偏移 |
INCRBY key integer | 给 value 增加 number ; value = value + number |
DECRBY key interger | value 减少 number ; value = value - number |
INCRBYFLOAT key increment | 由给定的数量递增键的浮点值 |
APPEND key value | 追加一个value到value的末尾 |
…
hash 散列
hash 理解为一个 string 嵌套了一个 string 能执行 string 的大部分操作
1. 解决的问题
我们通过多个 string kv 去储存一个 user 对象
"user:1:name" -> "张三" "user:1:age" -> 13 "user:2:name" -> "李四" ...
问题:
- 多key: redis 会产生很多键 key, key 过多会拖慢整个 redis
- 可读性差
- 浪费内存: key 也要空间, 前缀是重复的
- 管理困难: 如果要删除一个缓存就需要将所有字段的 key 都删除, 比如有 2 个字段就需要删除 2 个, 比如有 10 个字段就需要删除 10 个
2. 散列的储存结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6OQ9kuE7-1644494146691)(images/image-20220209113746280.png)]
3. 原语
原语 | 介绍 |
---|---|
HSET key field value [field value...] | 为字段设置值(不存在 field 会新建并返回 1 ,存在 field 覆盖并返回0) |
HGET key filed | 获取值(获取不到结果会返回 nil) |
HDEL key field | 删除 key 的 filed |
HSETNX key field value | 只在字段不存在的情况下为它设置值(filed 存在将会失败并返回 0) |
HINCRBY key field integer | 字段递增递减 |
HINCRBYFLOAT key field float | 字段递增浮点数 |
HSTRLEN key field | 获取字段长度 |
HEXISTS key field | 检查字段是否存在 |
HLEN key | 获取 key 字段个数 |
DEL key | 删除 key |
HMSET key field value [field value...] | 批量设置 HSET 也能这样用 |
HMGET key filed [field..] | 批量 get field |
HKEYS key | 获取 key 所有字段 |
HVALS key | 获取 key 所有 value |
HGETALL key | 获取 key 所有的字段和value |
list 列表
实现是双向链表或者说一个队列
1.储存结构
2.原语
原语 | 介绍 |
---|---|
LPUSH key element [element...] | 将成员推入列表左端 |
RPUSH key element [element...] | 将成员推入列表右端 |
LPUSHX key element [element...] | 将成员推入列表左端(key不存在返回0) |
RPUSHX key element [element...] | 将成员推入列表右端(key不存在返回0) |
LPOP key** ** | 弹出列表最左端的成员 |
RPOP key** ** | 弹出列表最右端的成员 |
RPOPLPUSH key | 将右端弹出的成员推入左端 |
LLEN key | 获取列表的长度 |
LINSERT key BEFORE|AFTER pivot element | 插入成员, pivot 是成员中点成员的值 |
LRANGE key start stop | 得到范围的成员集合, stop 为 -1 代表所有成员 |
LTRIM key start stop | 修建列表, 移除范围之类的所有成员 |
LREM key count element | 移除成员, count = 0 移除所有,count>0移除 count 个数 |
BLPOP key timeout | 阻塞式左端弹出 |
BRPOP key timeout | 阻塞式右端弹出 |
BRPOPLPUSH key timeout | 阻塞式将右端弹出的成员推入左端 |
set 集合
不重复的列表, 自动去重, 类似数据集合概念(内部实现是一个 value 为 null 的 hashmap)
1.储存结构
(内部实现是一个 value 为 null 的 hashmap)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dHrOdotu-1644494146692)(images/image-20220209143243515.png)]
2.原语
原语 | 介绍 |
---|---|
SADD key element [element...] | 将成员添加到集合 |
SREM key element | 从集合中移除成员 |
SMOVE source target element | 将成员从一个集合移动到另一个集合 |
SMEMBERS key | 获取集合中所有成员 |
SCARD key | 获取集合成员数量 |
SISMEMBER key element | 成员是否属于该集合 |
SRANDMEMBER key [count] | 随机获得集合成员, count 默认 为 1 |
SPOP key [count] | 随机弹出集合成员, count 默认 为 1 |
SINTER key [key...] | 返回多个集合的交集 |
SINTERSTORE target [key...] | 多个集合的交集储存到一个新的集合,返回新集合个数 |
SUNION [key...] | 返回多个集合的并集 |
SUNIONSTORE target [key...] | 多个集合的并集储存到一个新的集合,返回新集合个数 |
SDIFF [key...] | 返回多个集合的差集 |
SDIFFSTORE target [key...] | 多个集合的差集储存到一个新的集合,返回新集合个数 |
zset 有序集合
通过新增 score 字段来排序, -inf 和 +inf 代表正无穷和负无穷的分数, 分数一致的成员会使用字典排序
1.储存结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-td9ar9CF-1644494146692)(images/image-20220209164359582.png)]
2.原语
原语 | 介绍 |
---|---|
ZADD key score element[score element...] | 添加或者更新成员 |
ZREM key element | 移除成员 |
ZSCORE key element | 获取成员的分数 |
ZINCRBY key score element | 增加成员分数 |
ZCARD key | 获取集合成员个数 |
ZRANK key element | 获取成员升序排名 |
ZREVRANK key element | 获取成员降序排名 |
ZRANGE key start end | 获取排名区间成员(升序) |
ZREVRANGE key start end | 获取排名区间成员(降序) |
ZRANGEBYSCORE key min max | 获取分数区间的成员(升序) |
ZREVRANGEBYSCORE key max min | 获取分数区间的成员(降序) |
ZCOUNT key min max | 获取分数区间的成员个数(升序) |
ZREMRANGEBYRANK key start end | 移除排名区间的成员(升序), 负数可以实现倒数 |
ZREMRANGEBYSCORE key min max | 移除分数区间的成员(升序) |
ZUNIONSTORE target key [key...] | 多个集合的并集储存到一个新的集合,相同的 element 会累加 score |
ZRANGEBYLEX key min max [limit offset count] | 获取字典排序指定范围成员 |
ZREVRANGEBYLEX key min max [limit offset count] | 获取字典排序指定范围成员(降序) |
ZLEXCOUNT key min max | 获取字典排序指定范围成员数量 |
ZREMRANGEBYLEX key min max | 移除字典排序指定范围成员 |
ZPOPMAX key [count] | 弹出分值高的成员 |
ZPOPMIN key [count] | 弹出分值低的成员 |
BZPOPMAX key [key...] timeout | 阻塞弹出分值高的成员, 从多个 zset 中 select 弹出 |
BZPOPMIN key [key...] timeout | 阻塞弹出分值低的成员, 从多个 zset 中 select 弹出 |
HyperLogLog 集合唯一计数器
唯一计数器(12k就能计数2^64个成员, 计数估计算法误差0.81%)
- 统计集合成员的个数
- 并集多个 HyperLogLog
2.原语
原语 | 介绍 |
---|---|
PFADD key element [element...] | 添加成员(成功返回1,成员存在返回0) |
PFCOUNT key | 计数成员 |
PFMERGE target key [key...] | 并集 key |
bitmap 位图
bitmap 是一个二进制的bit数组, 能对指定的 offset 进行位操作
1. 数据结构
下面展示一个 1 byte = 8 bit(位) 的 bitmpa
位图存储的值为10010100
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ez8XcVCy-1644494146692)(images/image-20220209231147095.png)]
2.原语
原语 | 介绍 |
---|---|
SETBIT key offset 0|1 | 设置offset的值位(0或者1) |
GETBIT key offset | 获取offset的值位(0或者1) |
BITCOUNT key | 获取1的数量 |
BITPOS key 0|1 start end | 获取位的offset(注意: start end 的单位式 byte) |
BITOP target key [key...] | 一个或者多个bitmap执行位运算并将结果储存到 target 中(AND|OR|XOR|NOT) |
BITFIELD key SET type offset value | 设置整数值(type: i8 有符号8位, u8无符号8位,类推) |
BITFIELD key SET type #index value | 设置整数值(offset 变为 #index, #1 表示第一个 type 类型的位置) |
BITFIELD key GET type offset | 获取整数值 |
BITFIELD key GET type #index | 获取整数值(根据 index ) |
GET key | 可以使用 string 命令对 bitmiap 操作, 因为 bitmap 是基于 string 实现的 |
geo 地理坐标
2.原语
原语 | 介绍 |
---|---|
GEOADD key [NX|XX] x y name[key x y name...] | 设置坐标, x 经度, y 纬度, name 是别名, 返回已有的数量 |
GEOPOS key name[name...] | 获取坐标 |
GEODIST key name name | 计算 2 个坐标的距离 |
GEORADIUS key x y radius unit | 查找坐标半径内的其他成员, radius 是半径, unit 单位(m km mi ft) |
GEORADIUSBYMEMBER key name radius unit | 查找成员半径内的其他成员 |
stream 流(重要)
1. XADD 添加新元素到末尾
(1) id
XADD key id key value [key value...]
流元素的 id 由 毫秒时间戳 + 序列号组成 需要他们整体呈递增, 不然将会报错
id 使用 * 将自动生成 id
127.0.0.1:6379> XADD x1 * k1 v1 "1644465874779-0"
(2) 执行 XADD 同时用 MAXLEN 修剪流
注意观察, 这个是 XADD 执行时候修剪, 注意使用时机
127.0.0.1:6379> XADD x1 MAXLEN = 2 * k1 v1 "1644466561573-0" 127.0.0.1:6379> XADD x1 * k2 v2 "1644466573705-0" 127.0.0.1:6379> XRANGE x1 - + 1) 1) "1644466561573-0" 2) 1) "k1" 2) "v1" 2) 1) "1644466573705-0" 2) 1) "k2" 2) "v2" # 这里没有添加 MAXLEN 限制将不会生效 MAXLEN 127.0.0.1:6379> XADD x1 * k3 v3 "1644466587887-0" 127.0.0.1:6379> XRANGE x1 - + 1) 1) "1644466561573-0" 2) 1) "k1" 2) "v1" 2) 1) "1644466573705-0" 2) 1) "k2" 2) "v2" 3) 1) "1644466587887-0" 2) 1) "k3" 2) "v3" # 这里添加 MAXLEN 限制将会生效 MAXLEN 127.0.0.1:6379> XADD x1 MAXLEN = 2 * k4 v4 "1644466613469-0" 127.0.0.1:6379> XRANGE x1 - + 1) 1) "1644466587887-0" 2) 1) "k3" 2) "v3" 2) 1) "1644466613469-0" 2) 1) "k4" 2) "v4" 127.0.0.1:6379>
2. XTRIM 修剪流
我们除了执行 XADD 的时候同时使用 MAXLEN 修剪流, 我们也能用 XTRIM 单独修剪流
XTRIM key MAXLENTH|MINID =|~ threshold [limit count]
示例
127.0.0.1:6379> XRANGE x1 - + 1) 1) "1644466587887-0" 2) 1) "k3" 2) "v3" 2) 1) "1644466613469-0" 2) 1) "k4" 2) "v4" 127.0.0.1:6379> XTRIM x1 MAXLEN 1 (integer) 1 127.0.0.1:6379> XRANGE x1 - + 1) 1) "1644466613469-0" 2) 1) "k4" 2) "v4" 127.0.0.1:6379>
3. XDEL 移除流中的 ID
使用
XDEL key [id...]
示例
127.0.0.1:6379> XRANGE x1 - + 1) 1) "1-0" 2) 1) "k1" 2) "v1" 2) 1) "2-0" 2) 1) "k2" 2) "v2" 127.0.0.1:6379> XDEL x1 1-0 (integer) 1 127.0.0.1:6379> XRANGE x1 - + 1) 1) "2-0" 2) 1) "k2" 2) "v2" 127.0.0.1:6379>
4. XLEN 获取元素数量
XLEN key
示例
127.0.0.1:6379> XRANGE x1 - + 1) 1) "2-0" 2) 1) "k2" 2) "v2" 127.0.0.1:6379> XLEN x1 (integer) 1 127.0.0.1:6379>
5. XRANGE、XREVRANGE:访问流中元素
XRANGE 可以获取流的单个元素, 多个元素, 以及迭代整个流
XRANGE key start-id end-id [COUNT n]
迭代整个流可以通过每次访问用 COUNT 限制 1 个然后下一次访问的时候用 start-id 赋值位 上一次的成员的 id + 1
就能范围缩小从而迭代下一个元素
这里 start-id 将会获取大于等于 start-id 的成员
6. XREAD 从一个和多个 stream 用阻塞或者非阻塞的方式获取流
XREAD [COUNT n] [BLOCK milliseconds] STREAMS key [key...] id [id...]
这里 id 将会获取大于 id 的成员
如果 id 为 $ 将会仅仅获取命令执行之后的最新的流
BLOCK 有流就会返回, 比如要求有 COUNT 为 3, 只能读取到 2 个就直接返回 2 个.
7. XGROUP 消费组
(1) 创建消费组
XGROUP [CREATE key groupname id-or-$] [SETID key groupname id-or-$] [DESTROY key groupname] [DELCONSUMER key groupname consumername]
- key 为流的名称,不存在就创建
- groupname 是消费者的名称
- id-or-$: id 代表从 id 位置开始, $ 代表从尾部开始, 就是之前的信息会忽略
从头开始消费
XGROUP CREATE mystream groupname 0-0
只是消费最新的信息
XGROUP CREATE mystream groupname $
(2) 在消费组里消费信息
- 同一个 stream 可以创建多个消费组
- 同一个消费组的信息只能被一个消费者读取
XREADGROUP GROUP group consumer [COUNT count] [BLOCK milliseconds] [NOACK] STREAMS key [key ...] ID [ID ...]
同理 XREAD 命令, 新增的字段如下
- group 是创建的消费组的名称
- consumer 是消费者的名称, 用户自定义
- id: 消息的 id (
>
就是读取一条未递送的消息), 读取之后的消息同一个消息组的其他消费者将不能再次读取
127.0.0.1:6379> XADD x1 1 k1 v1 "1-0" # 创建 g1 消费组, 读取最新的内容 127.0.0.1:6379> XGROUP CREATE x1 g1 $ OK # 使用 c1 读取 g1 消费组中的内容, 没有最新内容返回 nil 127.0.0.1:6379> XREADGROUP GROUP g1 c1 STREAMS x1 > (nil) # 给 stream x1 添加内容, g1 会共享到 x1 的天降 127.0.0.1:6379> XADD x1 2 k2 v2 "2-0" # 使用 c1 读取 g1 消费组中的内容 127.0.0.1:6379> XREADGROUP GROUP g1 c1 STREAMS x1 > 1) 1) "x1" 2) 1) 1) "2-0" 2) 1) "k2" 2) "v2" # 使用 c1 读取 g1 消费组中的内容, 没有最新内容返回 nil 127.0.0.1:6379> XREADGROUP GROUP g1 c1 STREAMS x1 > (nil) # 使用 新的消费者 c2 读取 g1 消费组中的内容, 没有最新内容返回 nil, 一个消息在一个消费组里面只能被消费者消费一次 127.0.0.1:6379> XREADGROUP GROUP g1 c2 STREAMS x1 > (nil) # 消费者处理完消息之后发送 ACK 确认, 消息就从待处理变成已确认 127.0.0.1:6379> XACK x1 g1 2-0 (integer) 1 # 只能确认一次 127.0.0.1:6379> XACK x1 g1 2-0 (integer) 0 127.0.0.1:6379>
(3) XACK 确认
XACK key groupname id
通过 id 确认消息
消息添加后在消息组中 4 个状态
- 不存在
- 未递送
- 待处理
- 已确认
转换关系如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-g0O6zVS7-1644494146693)(images/image-20220210170444852.png)]
示例
127.0.0.1:6379> XREADGROUP GROUP g1 c1 STREAMS x1 > 1) 1) "x1" 2) 1) 1) "3-0" 2) 1) "k3" 2) "v3" # 查看没有确认的消息 127.0.0.1:6379> XPENDING x1 g1 1) (integer) 1 2) "3-0" 3) "3-0" 4) 1) 1) "c1" 2) "1" # 确认消息 127.0.0.1:6379> XACK x1 g1 3-0 (integer) 1 127.0.0.1:6379> XPENDING x1 g1 1) (integer) 0 2) (nil) 3) (nil) 4) (nil) 127.0.0.1:6379>
(4) 管理消费组
原语 | 介绍 |
---|---|
XGROUP SETID key groupname id | 修改消费组的id(消费组会读取大于id的消息,$代表最新的消息), 该命令会重置 group 的未读消息 |
XGROUP DELCOMSUMER key groupname consuemr | 删除消费者 |
XGROUP DISTORY key groupname | 删除消费组 |
8. 查看取待处理的消息
XPENDING key groupname [start stop count] [consumer]
(1) 查看所有消费者的待处理消息
127.0.0.1:6379> XPENDING x1 g1 1) (integer) 2 # 待处理消息数量 2) "3-0" # 首条未读消息的id 3) "4-0" # 最后一台未读消息的id 4) 1) 1) "c1" # 各个消费者目前正在处理消息的数量 2) "1" 2) 1) "c2" 2) "1" 127.0.0.1:6379>
(2) 查看具体一个消费者的待处理消息
127.0.0.1:6379> XPENDING x1 g1 - + 1 c1 1) 1) "4-0" # 消息 id 2) "c1" # 消费者 3) (integer) 3321593 # 消息处理的时间 4) (integer) 1 # 消息消费的次数 127.0.0.1:6379>
9. XCLAIM:转移消息的归属权
XCLAIM key groupname new_consuemr max_pending_time id [id...]
旧的消费者需要在 max_pending_time 的期限中 XACK 信息, 否则消息的归属权将会转移
10. XINFO:查看流和消费者组的相关信息
(1) HELP 帮助
127.0.0.1:6379> XINFO HELP 1) XINFO <subcommand> [<arg> [value] [opt] ...]. Subcommands are: 2) CONSUMERS <key> <groupname> # 1.展示 consuemr 信息 3) Show consumers of <groupname>. 4) GROUPS <key> # 2. 展示 group 信息 5) Show the stream consumer groups. 6) STREAM <key> [FULL [COUNT <count>] # 3. 展示 stream 消息 7) Show information about the stream. 8) HELP 9) Prints this help. 127.0.0.1:6379>
(2) CONSUMERS 查看消费组里的消费者
127.0.0.1:6379> XINFO CONSUMERS x1 g1 1) 1) "name" # 1. 消费者名称 2) "c1" 3) "pending" # 2. pending 4) (integer) 1 5) "idle" # 3. 处理的时间,还没有规范 6) (integer) 4116697 2) 1) "name" 2) "c2" 3) "pending" 4) (integer) 1 5) "idle" 6) (integer) 3980477 127.0.0.1:6379>
(3) STREAM 查看流的信息
127.0.0.1:6379> XINFO STREAM x1 1) "length" #成员数量 2) (integer) 4 3) "radix-tree-keys" #基树键的数量 4) (integer) 1 5) "radix-tree-nodes" # 基树节点的数量 6) (integer) 2 7) "last-generated-id" #最后一个节点的 id 8) "4-0" 9) "groups" #消费者数量 10) (integer) 1 11) "first-entry" #最开始的成员 12) 1) "1-0" 2) 1) "k1" 2) "v1" 13) "last-entry" #最后的成员 14) 1) "4-0" 2) 1) "k4" 2) "v4" 127.0.0.1:6379>
pub/sub 发布订阅
发布订阅就像广播, 是无状态的, 订阅者没有收到就丢失了, 不会储存旧信息也不会持久化
1. 发布订阅频道
发布者发布的消息能被多个订阅者接收
2. 发布订阅模式
模式匹配可以 一个 pattern 订阅多个模式
3.原语
原语 | 介绍 |
---|---|
PUBLISH key message | 发布者发布消息 |
SUBSCRIBE key [key...] | 订阅者订阅消息 |
UNSUBSCRIBE [key...] | 退订频道, 默认退订所有频道 |
PSUBSCRIBE pattern [pattern...] | 订阅模式, 一个 pattern 可以匹配多个频道 |
PUNSUBSCRIBE pattern [pattern...] | 退订模式 |
PUBSUB CHANNELS [pattern] | 列出目前被订阅的频道 |
PUBSUB NUMSUB [key ...] | 查询频道订阅的数量 |
PUBSUB NUMPAT | 查询频道订阅的总数 |
数据库
原语 | 介绍 |
---|---|
KEYS pattern | 返回匹配正则表达式的所有的 key |
EXISTS key | 时候存在 key |
DBSIZE | key 数量 |
TTL key | key 的过期时间(秒) |
PTTL key | key 的过期时间(毫秒) |
这篇关于[redis] 10 种数据结构详解的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-08阿里云Redis项目实战入门教程
- 2024-11-08阿里云Redis资料:新手入门与初级使用指南
- 2024-11-08阿里云Redis教程:新手入门及实用指南
- 2024-11-07阿里云Redis学习入门:新手必读指南
- 2024-11-07阿里云Redis学习入门:从零开始的操作指南
- 2024-11-07阿里云Redis学习:初学者指南
- 2024-11-06阿里云Redis入门教程:轻松搭建与使用指南
- 2024-11-02Redis项目实战:新手入门教程
- 2024-10-22Redis入门教程:轻松掌握数据存储与操作
- 2024-10-22Redis缓存入门教程:快速掌握Redis缓存基础知识