Redis入门学习教程,从入门到精通,Redis 数据操作:知识点详解与代码实战(2)

Redis 数据操作:知识点详解与代码实战

2.1 Redis 数据存储

2.1.1 Redis 数据库本质

Redis 是一个键值对数据库,所有的数据都通过唯一的键(Key)来访问。键是二进制安全的,可以是字符串、数字甚至序列化对象。

2.1.2 键的命名规范

bash 复制代码
# 好的命名示例
user:1001:name      # 用户ID为1001的姓名
article:9527:title  # 文章ID为9527的标题
order:20240316:001  # 订单号

# 命令示例
127.0.0.1:6379> SET user:1001:name "张三"
OK
127.0.0.1:6379> GET user:1001:name
"张三"

2.2 文本数据类型(String)

2.2.1 语法知识点

命令 语法 说明
SET `SET key value [EX seconds] [PX milliseconds] [NX XX]`
GET GET key 获取键对应的值
MSET MSET key1 value1 key2 value2 ... 批量设置多个键值对
MGET MGET key1 key2 ... 批量获取多个键的值
INCR INCR key 将键的值加1(原子操作)
DECR DECR key 将键的值减1(原子操作)
INCRBY INCRBY key increment 将键的值增加指定整数
DECRBY DECRBY key decrement 将键的值减少指定整数
APPEND APPEND key value 在原有值后追加字符串
STRLEN STRLEN key 获取字符串长度
GETRANGE GETRANGE key start end 获取子字符串
SETEX SETEX key seconds value 设置键值并指定过期时间
SETNX SETNX key value 键不存在时才设置(分布式锁)

2.2.2 案例代码

bash 复制代码
# 1. 基础设置与获取
127.0.0.1:6379> SET username "张三"
OK
127.0.0.1:6379> GET username
"张三"

# 2. 带过期时间的设置(缓存场景)
# 设置一个验证码,5分钟后过期
127.0.0.1:6379> SETEX verification:13800138000 300 "123456"
OK
# 或者使用SET命令的EX选项
127.0.0.1:6379> SET verification:13800138000 "123456" EX 300
OK

# 3. 批量操作
127.0.0.1:6379> MSET user:1:name "李四" user:1:age "25" user:1:city "北京"
OK
127.0.0.1:6379> MGET user:1:name user:1:age user:1:city
1) "李四"
2) "25"
3) "北京"

# 4. 原子计数器(实现网站访问量统计)
127.0.0.1:6379> SET page:home:views 1000
OK
127.0.0.1:6379> INCR page:home:views      # 访问量+1
(integer) 1001
127.0.0.1:6379> INCRBY page:home:views 100 # 批量增加100
(integer) 1101
127.0.0.1:6379> DECR page:home:views      # 访问量-1
(integer) 1100

# 5. 分布式锁实现(防止超卖)
127.0.0.1:6379> SETNX lock:product:1001 "thread-001"  # 尝试获取锁
(integer) 1  # 返回1表示获取成功
127.0.0.1:6379> SETNX lock:product:1001 "thread-002"  # 另一个线程尝试获取
(integer) 0  # 返回0表示获取失败,锁已被占用

# 6. 字符串操作
127.0.0.1:6379> SET message "Hello"
OK
127.0.0.1:6379> APPEND message " World!"  # 追加字符串
(integer) 12
127.0.0.1:6379> GET message
"Hello World!"
127.0.0.1:6379> STRLEN message  # 获取字符串长度
(integer) 12
127.0.0.1:6379> GETRANGE message 0 4  # 获取子串(0-4位置)
"Hello"

2.3 Hash 数据类型

2.3.1 语法知识点

命令 语法 说明
HSET HSET key field value [field value ...] 设置哈希表中的字段
HGET HGET key field 获取指定字段的值
HMSET HMSET key field1 value1 field2 value2 ... 批量设置多个字段
HMGET HMGET key field1 field2 ... 批量获取多个字段的值
HGETALL HGETALL key 获取所有字段和值
HKEYS HKEYS key 获取所有字段名
HVALS HVALS key 获取所有字段值
HEXISTS HEXISTS key field 判断字段是否存在
HDEL HDEL key field [field ...] 删除一个或多个字段
HLEN HLEN key 获取字段数量
HINCRBY HINCRBY key field increment 为字段值增加整数
HSETNX HSETNX key field value 字段不存在时才设置

2.3.2 案例代码

bash 复制代码
# 1. 存储用户信息(对象存储)
127.0.0.1:6379> HSET user:1001 username "王五" age "30" email "wangwu@example.com"
(integer) 3

# 2. 获取单个字段
127.0.0.1:6379> HGET user:1001 username
"王五"
127.0.0.1:6379> HGET user:1001 age
"30"

# 3. 批量获取多个字段
127.0.0.1:6379> HMGET user:1001 username age email
1) "王五"
2) "30"
3) "wangwu@example.com"

# 4. 获取所有字段和值
127.0.0.1:6379> HGETALL user:1001
1) "username"
2) "王五"
3) "age"
4) "30"
5) "email"
6) "wangwu@example.com"

# 5. 获取所有字段名
127.0.0.1:6379> HKEYS user:1001
1) "username"
2) "age"
3) "email"

# 6. 获取所有字段值
127.0.0.1:6379> HVALS user:1001
1) "王五"
2) "30"
3) "wangwu@example.com"

# 7. 更新用户年龄(原子操作)
127.0.0.1:6379> HINCRBY user:1001 age 1  # 年龄加1岁
(integer) 31
127.0.0.1:6379> HGET user:1001 age
"31"

# 8. 购物车实现
127.0.0.1:6379> HSET cart:user:1001 product:101 2  # 商品101加入2件
(integer) 1
127.0.0.1:6379> HSET cart:user:1001 product:102 1  # 商品102加入1件
(integer) 1
127.0.0.1:6379> HGETALL cart:user:1001
1) "product:101"
2) "2"
3) "product:102"
4) "1"
127.0.0.1:6379> HDEL cart:user:1001 product:101  # 删除商品101
(integer) 1
127.0.0.1:6379> HLEN cart:user:1001  # 购物车商品数量
(integer) 1

2.4 List 数据类型

2.4.1 语法知识点

命令 语法 说明
LPUSH LPUSH key value [value ...] 从左侧插入元素
RPUSH RPUSH key value [value ...] 从右侧插入元素
LPOP LPOP key 从左侧移除并返回元素
RPOP RPOP key 从右侧移除并返回元素
LLEN LLEN key 获取列表长度
LRANGE LRANGE key start stop 获取指定范围的元素
LINDEX LINDEX key index 通过索引获取元素
LSET LSET key index value 通过索引设置元素值
LINSERT `LINSERT key BEFORE AFTER pivot value`
LREM LREM key count value 移除指定数量的元素
LTRIM LTRIM key start stop 截取列表保留指定范围
BLPOP BLPOP key [key ...] timeout 阻塞式左侧弹出
BRPOP BRPOP key [key ...] timeout 阻塞式右侧弹出

2.4.2 案例代码

bash 复制代码
# 1. 消息队列实现(先进先出)
127.0.0.1:6379> RPUSH message:queue "用户登录" "订单创建" "支付成功"  # 右侧入队
(integer) 3
127.0.0.1:6379> LPOP message:queue  # 左侧出队(先进先出)
"用户登录"
127.0.0.1:6379> LPOP message:queue
"订单创建"

# 2. 栈实现(后进先出)
127.0.0.1:6379> LPUSH stack:history "/home" "/about" "/contact"  # 左侧入栈
(integer) 3
127.0.0.1:6379> LPOP stack:history  # 左侧出栈(后进先出)
"/contact"
127.0.0.1:6379> LPOP stack:history
"/about"

# 3. 分页查询(LRANGE)
127.0.0.1:6379> RPUSH article:comments "评论1" "评论2" "评论3" "评论4" "评论5"
(integer) 5
# 获取第1页,每页2条(索引0-1)
127.0.0.1:6379> LRANGE article:comments 0 1
1) "评论1"
2) "评论2"
# 获取第2页,每页2条(索引2-3)
127.0.0.1:6379> LRANGE article:comments 2 3
1) "评论3"
2) "评论4"
# 获取所有元素
127.0.0.1:6379> LRANGE article:comments 0 -1
1) "评论1"
2) "评论2"
3) "评论3"
4) "评论4"
5) "评论5"

# 4. 阻塞队列(实现生产者-消费者模式)
# 消费者A(阻塞等待消息,超时时间10秒)
127.0.0.1:6379> BLPOP task:queue 10
# 如果队列为空,会阻塞等待,直到有消息或超时

# 生产者B(生产消息)
127.0.0.1:6379> RPUSH task:queue "处理订单ID:12345"
(integer) 1
# 此时消费者A立即收到消息

# 5. 列表修剪(固定长度队列)
127.0.0.1:6379> RPUSH recent:search "手机" "电脑" "平板" "相机" "耳机"
(integer) 5
# 只保留最近3条搜索记录
127.0.0.1:6379> LTRIM recent:search -3 -1
OK
127.0.0.1:6379> LRANGE recent:search 0 -1
1) "平板"
2) "相机"
3) "耳机"

# 6. 列表元素操作
127.0.0.1:6379> RPUSH fruits "苹果" "香蕉" "橙子" "苹果" "葡萄"
(integer) 5
127.0.0.1:6379> LLEN fruits  # 列表长度
(integer) 5
127.0.0.1:6379> LINDEX fruits 2  # 获取索引2的元素
"橙子"
127.0.0.1:6379> LSET fruits 1 "草莓"  # 修改索引1的元素
OK
127.0.0.1:6379> LREM fruits 2 "苹果"  # 移除2个"苹果"
(integer) 2
127.0.0.1:6379> LRANGE fruits 0 -1
1) "草莓"
2) "橙子"
3) "葡萄"

2.5 Set 数据类型

2.5.1 语法知识点

命令 语法 说明
SADD SADD key member [member ...] 向集合添加元素
SREM SREM key member [member ...] 移除集合中的元素
SMEMBERS SMEMBERS key 获取集合所有元素
SISMEMBER SISMEMBER key member 判断元素是否在集合中
SCARD SCARD key 获取集合元素数量
SPOP SPOP key [count] 随机移除并返回指定数量元素
SRANDMEMBER SRANDMEMBER key [count] 随机获取指定数量元素
SINTER SINTER key [key ...] 求多个集合的交集
SUNION SUNION key [key ...] 求多个集合的并集
SDIFF SDIFF key [key ...] 求多个集合的差集
SMOVE SMOVE source destination member 将元素从一个集合移动到另一个

2.5.2 案例代码

bash 复制代码
# 1. 标签系统实现
127.0.0.1:6379> SADD article:1001:tags "Java" "Redis" "数据库"
(integer) 3
127.0.0.1:6379> SADD article:1002:tags "Python" "Redis" "Web"
(integer) 3
127.0.0.1:6379> SADD article:1003:tags "Java" "Spring" "微服务"
(integer) 3

# 2. 查看文章的标签
127.0.0.1:6379> SMEMBERS article:1001:tags
1) "Java"
2) "Redis"
3) "数据库"

# 3. 判断文章是否有某个标签
127.0.0.1:6379> SISMEMBER article:1001:tags "Redis"
(integer) 1  # 1表示存在
127.0.0.1:6379> SISMEMBER article:1001:tags "Python"
(integer) 0  # 0表示不存在

# 4. 标签数量统计
127.0.0.1:6379> SCARD article:1001:tags
(integer) 3

# 5. 标签推荐(共同标签)
# 查找同时使用Java和Redis的文章(交集)
127.0.0.1:6379> SINTER article:1001:tags article:1002:tags
1) "Redis"  # 两篇文章的共同标签

# 6. 推荐系统(共同关注)
127.0.0.1:6379> SADD user:1001:follow "user:1002" "user:1003" "user:1004"
(integer) 3
127.0.0.1:6379> SADD user:1005:follow "user:1002" "user:1006" "user:1007"
(integer) 3
# 查找共同关注的人
127.0.0.1:6379> SINTER user:1001:follow user:1005:follow
1) "user:1002"
# 推荐可能认识的人(差集:user:1001关注了但user:1005没关注的人)
127.0.0.1:6379> SDIFF user:1001:follow user:1005:follow
1) "user:1003"
2) "user:1004"

# 7. 抽奖系统实现
127.0.0.1:6379> SADD lottery:20240316 "用户A" "用户B" "用户C" "用户D" "用户E"
(integer) 5
# 随机抽取1名中奖者(不移除)
127.0.0.1:6379> SRANDMEMBER lottery:20240316 1
1) "用户C"
# 随机抽取3名中奖者(移除)
127.0.0.1:6379> SPOP lottery:20240316 3
1) "用户A"
2) "用户B"
3) "用户E"
# 查看剩余参与者
127.0.0.1:6379> SMEMBERS lottery:20240316
1) "用户C"
2) "用户D"

# 8. 唯一访客统计
127.0.0.1:6379> SADD page:home:visitors:20240316 "192.168.1.1" "192.168.1.2" "192.168.1.1"
(integer) 2  # 重复IP只添加一次
127.0.0.1:6379> SCARD page:home:visitors:20240316  # 独立访客数
(integer) 2

2.6 ZSet 数据类型

2.6.1 语法知识点

命令 语法 说明
ZADD ZADD key score member [score member ...] 添加元素及分值
ZRANGE ZRANGE key start stop [WITHSCORES] 按排名范围获取元素
ZREVRANGE ZREVRANGE key start stop [WITHSCORES] 按排名倒序获取元素
ZRANK ZRANK key member 获取元素排名(正序)
ZREVRANK ZREVRANK key member 获取元素排名(倒序)
ZSCORE ZSCORE key member 获取元素的分值
ZCARD ZCARD key 获取集合元素数量
ZCOUNT ZCOUNT key min max 统计分值范围内的元素数量
ZINCRBY ZINCRBY key increment member 为元素增加分值
ZREM ZREM key member [member ...] 移除一个或多个元素
ZRANGEBYSCORE ZRANGEBYSCORE key min max [WITHSCORES] 按分值范围获取元素
ZREMRANGEBYRANK ZREMRANGEBYRANK key start stop 按排名范围移除元素
ZREMRANGEBYSCORE ZREMRANGEBYSCORE key min max 按分值范围移除元素

2.6.2 案例代码

bash 复制代码
# 1. 游戏排行榜实现
127.0.0.1:6379> ZADD game:leaderboard 1500 "玩家A" 2800 "玩家B" 3200 "玩家C" 2100 "玩家D"
(integer) 4

# 2. 查看排行榜(从高到低)
127.0.0.1:6379> ZREVRANGE game:leaderboard 0 -1 WITHSCORES
1) "玩家C"
2) "3200"
3) "玩家B"
4) "2800"
5) "玩家D"
6) "2100"
7) "玩家A"
8) "1500"

# 3. 查看前3名(Top3)
127.0.0.1:6379> ZREVRANGE game:leaderboard 0 2 WITHSCORES
1) "玩家C"
2) "3200"
3) "玩家B"
4) "2800"
5) "玩家D"
6) "2100"

# 4. 查看玩家排名和分数
127.0.0.1:6379> ZREVRANK game:leaderboard "玩家D"  # 排名(从0开始)
(integer) 2  # 第3名
127.0.0.1:6379> ZSCORE game:leaderboard "玩家D"
"2100"

# 5. 玩家分数更新(玩家B胜利加分)
127.0.0.1:6379> ZINCRBY game:leaderboard 500 "玩家B"
"3300"
127.0.0.1:6379> ZREVRANGE game:leaderboard 0 -1 WITHSCORES
1) "玩家B"  # 上升到第1名
2) "3300"
3) "玩家C"
4) "3200"
5) "玩家D"
6) "2100"
7) "玩家A"
8) "1500"

# 6. 按分数范围查询(查询2000-3000分的玩家)
127.0.0.1:6379> ZRANGEBYSCORE game:leaderboard 2000 3000 WITHSCORES
1) "玩家D"
2) "2100"
3) "玩家C"
4) "3200"  # 注意:3200分超出了范围,说明命令有误
# 正确写法:使用-inf和+inf表示无穷
127.0.0.1:6379> ZRANGEBYSCORE game:leaderboard 2000 3000 WITHSCORES
1) "玩家D"
2) "2100"

# 7. 统计不同分数段的人数
127.0.0.1:6379> ZCOUNT game:leaderboard 0 2000   # 0-2000分人数
(integer) 2
127.0.0.1:6379> ZCOUNT game:leaderboard 2001 3000  # 2001-3000分人数
(integer) 1
127.0.0.1:6379> ZCOUNT game:leaderboard 3001 5000  # 3001-5000分人数
(integer) 1

# 8. 延迟队列实现(使用时间戳作为分数)
# 添加延迟任务(计划在5分钟后执行)
127.0.0.1:6379> ZADD task:delay 1615891200 "send_email:user1001"
(integer) 1
127.0.0.1:6379> ZADD task:delay 1615891500 "send_email:user1002"
(integer) 1
127.0.0.1:6379> ZADD task:delay 1615891800 "send_email:user1003"
(integer) 1

# 查询当前时间(1615891300)之前需要执行的任务
127.0.0.1:6379> ZRANGEBYSCORE task:delay -inf 1615891300
1) "send_email:user1001"

# 9. 热门文章排行榜(根据点击量)
127.0.0.1:6379> ZADD hot:articles 1000 "article:101" 800 "article:102" 1200 "article:103"
(integer) 3
# 文章点击量增加
127.0.0.1:6379> ZINCRBY hot:articles 300 "article:101"
"1300"
# 查看热门文章Top3
127.0.0.1:6379> ZREVRANGE hot:articles 0 2 WITHSCORES
1) "article:101"
2) "1300"
3) "article:103"
4) "1200"
5) "article:102"
6) "800"

2.7 位操作(Bitmap)

2.7.1 语法知识点

命令 语法 说明
SETBIT SETBIT key offset value 设置指定偏移量的位(0或1)
GETBIT GETBIT key offset 获取指定偏移量的位
BITCOUNT BITCOUNT key [start end] 统计值为1的位的数量
BITOP BITOP operation destkey key [key ...] 位运算(AND/OR/XOR/NOT)
BITPOS BITPOS key bit [start] [end] 查找第一个指定值的位的位置

2.7.2 案例代码

bash 复制代码
# 1. 用户签到系统(一年365天,使用365个位)
# 用户1001在2024年第1天、第10天、第100天签到
127.0.0.1:6379> SETBIT user:1001:sign:2024 0 1    # 第1天签到
(integer) 0
127.0.0.1:6379> SETBIT user:1001:sign:2024 9 1    # 第10天签到
(integer) 0
127.0.0.1:6379> SETBIT user:1001:sign:2024 99 1   # 第100天签到
(integer) 0

# 2. 查询用户某天是否签到
127.0.0.1:6379> GETBIT user:1001:sign:2024 0    # 第1天
(integer) 1
127.0.0.1:6379> GETBIT user:1001:sign:2024 1    # 第2天
(integer) 0

# 3. 统计用户2024年签到总天数
127.0.0.1:6379> BITCOUNT user:1001:sign:2024
(integer) 3

# 4. 连续签到天数查询
127.0.0.1:6379> SETBIT user:1002:sign:2024 0 1
127.0.0.1:6379> SETBIT user:1002:sign:2024 1 1
127.0.0.1:6379> SETBIT user:1002:sign:2024 2 1
# 查找第一个0的位置(即断签的第一天)
127.0.0.1:6379> BITPOS user:1002:sign:2024 0
(integer) 3  # 第4天开始断签,说明连续签到了3天

# 5. 活跃用户统计(每天一个Bitmap)
# 记录2024-03-16的活跃用户(用户ID作为偏移量)
127.0.0.1:6379> SETBIT active:20240316 1001 1
(integer) 0
127.0.0.1:6379> SETBIT active:20240316 1002 1
(integer) 0
127.0.0.1:6379> SETBIT active:20240316 1005 1
(integer) 0

# 2024-03-17的活跃用户
127.0.0.1:6379> SETBIT active:20240317 1001 1
(integer) 0
127.0.0.1:6379> SETBIT active:20240317 1003 1
(integer) 0
127.0.0.1:6379> SETBIT active:20240317 1005 1
(integer) 0

# 6. 统计连续两天都活跃的用户(交集)
127.0.0.1:6379> BITOP AND active:both active:20240316 active:20240317
(integer) 126  # 返回字节长度
127.0.0.1:6379> BITCOUNT active:both  # 统计连续活跃用户数
(integer) 2  # 用户1001和1005

# 7. 统计任意一天活跃过的用户(并集)
127.0.0.1:6379> BITOP OR active:either active:20240316 active:20240317
(integer) 126
127.0.0.1:6379> BITCOUNT active:either
(integer) 4  # 用户1001、1002、1003、1005

# 8. 在线状态监控(5分钟更新一次)
# 用户1001在线
127.0.0.1:6379> SETBIT online:users 1001 1
(integer) 0
# 30秒后检查用户是否还在线
127.0.0.1:6379> GETBIT online:users 1001
(integer) 1

2.8 HyperLogLog

2.8.1 语法知识点

命令 语法 说明
PFADD PFADD key element [element ...] 添加元素到HyperLogLog
PFCOUNT PFCOUNT key [key ...] 返回基数估算值
PFMERGE PFMERGE destkey sourcekey [sourcekey ...] 合并多个HyperLogLog

2.8.2 案例代码

bash 复制代码
# 1. UV统计(独立访客)- 每天只需12KB内存
# 记录今天访问网站的用户ID
127.0.0.1:6379> PFADD uv:20240316 "user:1001" "user:1002" "user:1003" "user:1001"
(integer) 1  # 重复的user:1001只记录一次

# 2. 获取今天的UV估算值
127.0.0.1:6379> PFCOUNT uv:20240316
(integer) 3  # 近似值,真实值也是3

# 3. 模拟大量数据测试
127.0.0.1:6379> PFADD uv:20240317 "user:1001" "user:1004" "user:1005" "user:1006" "user:1007" "user:1008"
(integer) 1
127.0.0.1:6379> PFCOUNT uv:20240317
(integer) 6

# 4. 合并多天的UV数据(统计月度UV)
127.0.0.1:6379> PFMERGE uv:202403 uv:20240316 uv:20240317
OK
127.0.0.1:6379> PFCOUNT uv:202403  # 合并后的独立访客数
(integer) 7  # user:1001只统计一次,共7个独立用户

# 5. 搜索引擎不同搜索词的独立用户统计
127.0.0.1:6379> PFADD search:redis "userA" "userB" "userC"
(integer) 1
127.0.0.1:6379> PFADD search:redis "userA" "userD"  # 继续添加
(integer) 1
127.0.0.1:6379> PFCOUNT search:redis
(integer) 4  # 独立用户:userA、userB、userC、userD

# 6. 不同搜索词的独立用户对比
127.0.0.1:6379> PFADD search:mysql "userA" "userB" "userE"
(integer) 1
127.0.0.1:6379> PFADD search:mongodb "userC" "userF" "userG"
(integer) 1
# 统计所有搜索过的独立用户
127.0.0.1:6379> PFMERGE search:all search:redis search:mysql search:mongodb
OK
127.0.0.1:6379> PFCOUNT search:all
(integer) 7  # 所有不重复用户

2.9 GEO 数据类型

2.9.1 语法知识点

命令 语法 说明
GEOADD GEOADD key longitude latitude member [longitude latitude member ...] 添加地理位置
GEOPOS GEOPOS key member [member ...] 获取位置坐标
GEODIST `GEODIST key member1 member2 [m km
GEORADIUS `GEORADIUS key longitude latitude radius m km
GEORADIUSBYMEMBER `GEORADIUSBYMEMBER key member radius m km
GEOHASH GEOHASH key member [member ...] 获取位置的Geohash值

2.9.2 案例代码

bash 复制代码
# 1. 添加店铺位置(经度 纬度 店名)
127.0.0.1:6379> GEOADD shops 116.397128 39.916527 "天安门店" 116.327933 39.980278 "鸟巢店" 116.457951 39.872989 "国贸店"
(integer) 3

# 2. 添加更多餐饮店铺
127.0.0.1:6379> GEOADD restaurants 116.391284 39.907377 "全聚德前门店" 116.326749 39.981315 "全聚德亚运村店" 116.461087 39.913148 "海底捞国贸店"
(integer) 3

# 3. 获取店铺坐标
127.0.0.1:6379> GEOPOS restaurants "全聚德前门店"
1) 1) "116.39128494262695312"
   2) "39.90737774454291936"

# 4. 计算两家店之间的距离
127.0.0.1:6379> GEODIST restaurants "全聚德前门店" "全聚德亚运村店" km
"8.3654"  # 距离约8.37公里

# 5. 查找附近的人/店(LBS应用)
# 以天安门广场(116.397,39.908)为中心,查找5公里内的店铺
127.0.0.1:6379> GEORADIUS restaurants 116.397 39.908 5 km WITHCOORD WITHDIST
1) 1) "全聚德前门店"
   2) "0.3166"  # 距离约317米
   3) 1) "116.39128494262695312"
      2) "39.90737774454291936"

# 6. 查找附近餐厅,按距离排序,限制返回3条
127.0.0.1:6379> GEORADIUS restaurants 116.397 39.908 10 km WITHDIST ASC COUNT 3
1) 1) "全聚德前门店"
   2) "0.3166"
2) 1) "海底捞国贸店"
   2) "5.2341"
3) 1) "全聚德亚运村店"
   2) "8.3654"

# 7. 以指定成员为中心查找(找全聚德前门店附近的餐馆)
127.0.0.1:6379> GEORADIUSBYMEMBER restaurants "全聚德前门店" 3 km WITHDIST
1) 1) "全聚德前门店"
   2) "0.0000"  # 自身距离为0
2) 1) "海底捞国贸店"
   2) "2.9183"

# 8. 获取Geohash值(可用于索引和缓存)
127.0.0.1:6379> GEOHASH restaurants "全聚德前门店"
1) "wx4g0r7k230"

# 9. 找附近的人(社交应用)
127.0.0.1:6379> GEOADD users 116.398 39.909 "user:1001" 116.410 39.920 "user:1002" 116.330 39.980 "user:1003"
(integer) 3

# 查找user:1001附近5公里内的用户
127.0.0.1:6379> GEORADIUSBYMEMBER users "user:1001" 5 km WITHDIST
1) 1) "user:1001"
   2) "0.0000"
2) 1) "user:1002"
   2) "1.8234"  # 约1.82公里

通过本章的学习,你应该能够熟练掌握 Redis 的各种数据结构,并能根据实际业务场景选择合适的数据类型。每种数据类型都有其独特的优势和适用场景:

  • String:缓存、计数器、分布式锁
  • Hash:对象存储、购物车
  • List:消息队列、时间线、栈
  • Set:标签系统、社交关系、抽奖
  • ZSet:排行榜、延迟队列、优先级队列
  • Bitmap:签到统计、活跃用户、布隆过滤器
  • HyperLogLog:UV统计、基数估算
  • GEO:LBS应用、附近的人、位置服务

在实际开发中,合理选择数据结构可以极大地提升系统性能和开发效率。

相关推荐
m0_662577971 小时前
Python迭代器(Iterator)揭秘:for循环背后的故事
jvm·数据库·python
似水明俊德1 小时前
12-C#
开发语言·数据库·oracle·c#
red_redemption2 小时前
自由学习记录(138)
学习
FirstFrost --sy2 小时前
MySQL关于表的操作
数据库·mysql
夏日听雨眠2 小时前
文件学习8
学习
青槿吖3 小时前
【保姆级教程】Spring事务控制通关指南:XML+注解双版本,避坑指南全奉上
xml·java·开发语言·数据库·sql·spring·mybatis
浪潮IT馆3 小时前
Windows 达梦 8(DM8)数据库完整安装教程 + 命令行导入 .dmp 文件完整指南
数据库·windows
Dylan~~~3 小时前
Redis MCP Server:让 AI 拥有“持久记忆“的革命性方案
数据库·人工智能·redis
小小怪7503 小时前
超越Python:下一步该学什么编程语言?
jvm·数据库·python