第四十三:redis 查找所有KEY应用方法

使用KEYS 查找所有的key 模糊查询key前缀

Go 复制代码
func (c Client) Keys(pattern string) *StringSliceCmd

keys, _ := client.Keys(search).Result()

获取所有的KEYS ,可以使用 keys ,scan

//上下文对象

var ctx = context.Background()
// 使用Scan方法遍历所有键
iter := client.Scan(ctx, 0, "*", 0).Iterator()
for iter.Next(ctx) {
key := iter.Val()
fmt.Println(key)
}

复制代码
SCAN cursor [MATCH pattern] [COUNT count]

cursor:游标的位置。第一次调用 SCAN 时,应该设置为 0。
MATCH pattern:可选参数,用于指定要匹配的键的模式。
COUNT count:可选参数,指定在每次迭代中返回的键的最大数量。


1. 基本的 SCAN 命令
bash
Copy Code
SCAN 0
这将返回所有键,但通常不推荐这样做,因为可能会返回大量数据。

2. 使用 MATCH 过滤键
假设我们只想获取所有以 user: 开头的键:

bash
Copy Code
SCAN 0 MATCH "user:*"
3. 使用 COUNT 控制返回的键的数量
为了减少单次调用的数据量,可以限制返回的键的数量:

bash
Copy Code
SCAN 0 MATCH "user:*" COUNT 10


python 实例:

import redis

r = redis.Redis()
cursor = '0'
pattern = 'user:*'
count = 10

while True:
    cursor, keys = r.scan(cursor=cursor, match=pattern, count=count)
    for key in keys:
        print(key)
    if cursor == '0':
        break


对于需要原子性操作的场景(例如,确保在短时间内不会丢失任何键),可以考虑使用 SSCAN, HSCAN, 或 ZSCAN 命令,这些是专门为集合、哈希表和有序集合设计的迭代器。但基本原理与 SCAN 相同。

redis.call('DECRBY') 举出实例

https://www.jb51.net/database/340685ucb.htm

https://www.cnblogs.com/ycfenxi/p/19216134

https://www.cnblogs.com/JerryQTQcjl/p/13359695.html

Go 复制代码
redis.call('DECRBY', key, decrement) 是 Redis Lua 脚本中的一个命令,用于将存储在 key 中的数字值减少指定的 decrement 量。如果 key 不存在,则会先将其设置为 0,然后执行减法操作。

实例说明
1. 基本用法
lua
编辑
redis.call('SET', 'counter', 100)  -- 设置初始值为 100
local result = redis.call('DECRBY', 'counter', 30)  -- 减少 30
-- 此时 'counter' 的值变为 70,result = 70
2. 负数增量(相当于增加)
lua
编辑
redis.call('SET', 'score', 50)  -- 设置初始值为 50
local result = redis.call('DECRBY', 'score', -10)  -- 减少 -10(相当于增加 10)
-- 此时 'score' 的值变为 60,result = 60
3. 键不存在时的默认行为
lua
编辑
local result = redis.call('DECRBY', 'new_counter', 20)  -- 'new_counter' 不存在
-- Redis 会先将 'new_counter' 设置为 0,然后减去 20
-- 最终 'new_counter' 的值为 -20,result = -20
4. 在购物车库存管理中的应用
lua
编辑
-- 假设库存键为 'product:1:inventory',当前库存为 100
redis.call('SET', 'product:1:inventory', 100)

-- 用户购买 30 件商品,减少库存
local new_stock = redis.call('DECRBY', 'product:1:inventory', 30)
-- 此时库存变为 70,new_stock = 70
5. 与 INCRBY 的对比
lua
编辑
redis.call('SET', 'balance', 1000)

-- 使用 DECRBY 减少余额(如扣款)
local new_balance1 = redis.call('DECRBY', 'balance', 100)  -- 扣除 100
-- balance 变为 900

-- 使用 INCRBY 增加余额(如充值)
local new_balance2 = redis.call('INCRBY', 'balance', 50)  -- 增加 50
-- balance 变为 950
注意事项
DECRBY 只能用于存储数字值的键,如果键存储的是非数字值,会返回错误
减量值可以是负数,此时效果等同于 INCRBY(增加)
如果键不存在,Redis 会先将其设置为 0,然后执行减法操作
这个命令在 Redis Lua 脚本中常用于实现原子性的计数器操作、库存管理、积分系统等场景。

以下是修正后的 Redis Lua 脚本:

Go 复制代码
-- KEYS[1] = cartKey (e.g., "user:123:cart")
-- KEYS[2] = inventoryKey (e.g., "product:1:inventory")
-- ARGV[1] = operation ("add" or "subtract")
-- ARGV[2] = quantity (string number, e.g., "2")
-- ARGV[3] = productId (e.g., "product:1")

local cartKey = KEYS[1]
local inventoryKey = KEYS[2]
local operation = ARGV[1]
local quantity = tonumber(ARGV[2])
local productId = ARGV[3]

-- 获取当前购物车中的数量,若不存在则为 0
local currentQuantity = tonumber(redis.call('HGET', cartKey, productId)) or 0

-- 获取库存
local stock = tonumber(redis.call('GET', inventoryKey))
if not stock then
    stock = 0
end

if operation == 'add' then
    if currentQuantity + quantity > stock then
        return 0  -- 库存不足
    end
    redis.call('HINCRBY', cartKey, productId, quantity)
    redis.call('DECRBY', inventoryKey, quantity)
elseif operation == 'subtract' then
    if currentQuantity < quantity then
        return 0  -- 购物车数量不足
    end
    redis.call('HINCRBY', cartKey, productId, -quantity)
    redis.call('INCRBY', inventoryKey, quantity)  -- 归还库存!
else
    return -1  -- 无效操作
end

return 1

调用方式

Go 复制代码
script = """...上面的 Lua 脚本..."""
redis.eval(script, 2, 'user:123:cart', 'product:1:inventory', 'add', '2', 'product:1')



local sha = redis.call('SCRIPT', 'LOAD', shoppingCartOperation)
redis.call('EVALSHA', sha, 2, cartKey, inventoryKey, operation, quantity, productId)
  • 定义一个本地函数,接收四个参数:
    • cartKey:用户购物车的哈希键(如 'user:123:cart'
    • inventoryKey:商品库存的字符串键(如 'product:1:inventory'
    • operation:操作类型('add''subtract'
    • quantity:操作数量
Go 复制代码
-- 修正后的 Redis Lua 脚本
-- KEYS[1]: 购物车哈希键 (如 "user:123:cart")
-- KEYS[2]: 库存字符串键 (如 "product:1:inventory")
-- ARGV[1]: 操作类型 ("add" 或 "subtract")
-- ARGV[2]: 操作数量 (如 "2")
-- ARGV[3]: 商品ID (如 "product:1")

local cartKey = KEYS[1]
local inventoryKey = KEYS[2]
local operation = ARGV[1]
local quantity = tonumber(ARGV[2])
local productId = ARGV[3]

-- 获取当前购物车中商品的数量,如果不存在则为0
local currentQuantity = tonumber(redis.call('HGET', cartKey, productId)) or 0

-- 获取当前库存
local stock = tonumber(redis.call('GET', inventoryKey)) or 0

if operation == 'add' then
    -- 添加商品时检查库存是否足够
    if currentQuantity + quantity > stock then
        return {error = "库存不足", code = 0}
    end
    -- 增加购物车数量
    redis.call('HINCRBY', cartKey, productId, quantity)
    -- 减少库存
    redis.call('DECRBY', inventoryKey, quantity)
elseif operation == 'subtract' then
    -- 减少商品时检查购物车数量是否足够
    if currentQuantity < quantity then
        return {error = "购物车数量不足", code = 0}
    end
    -- 减少购物车数量
    redis.call('HINCRBY', cartKey, productId, -quantity)
    -- 增加库存(归还商品)
    redis.call('INCRBY', inventoryKey, quantity)
else
    return {error = "无效操作", code = -1}
end

return {success = true, code = 1, message = "操作成功"}
相关推荐
·云扬·7 分钟前
MySQL 8.0 Redo Log 归档与禁用实战指南
android·数据库·mysql
IT邦德10 分钟前
Oracle 26ai DataGuard 搭建(RAC到单机)
数据库·oracle
惊讶的猫36 分钟前
redis分片集群
数据库·redis·缓存·分片集群·海量数据存储·高并发写
不爱缺氧i44 分钟前
完全卸载MariaDB
数据库·mariadb
期待のcode1 小时前
Redis的主从复制与集群
运维·服务器·redis
纤纡.1 小时前
Linux中SQL 从基础到进阶:五大分类详解与表结构操作(ALTER/DROP)全攻略
linux·数据库·sql
jiunian_cn1 小时前
【Redis】渐进式遍历
数据库·redis·缓存
橙露1 小时前
Spring Boot 核心原理:自动配置机制与自定义 Starter 开发
java·数据库·spring boot
冰暮流星1 小时前
sql语言之分组语句group by
java·数据库·sql
符哥20081 小时前
Ubuntu 常用指令集大全(附实操实例)
数据库·ubuntu·postgresql