Linux C/C++ 学习日记(61):Redis(二):多种数据结构的操作指令

Linux C/C++ 学习日记(61):Redis(二):多种数据结构的操作指令

注:该文用于个人学习记录和知识交流,如有不足,欢迎指点。

一、redis是kv数据库

key:string
value:5 大基础核心结构String(字符串)Hash(哈希)List(列表)Set(集合)Sorted Set/ZSet(有序集合)。

【 另外还有 位图(Bitmap)、地理空间(Geo) 等常用扩展结构(基于基础结构实现)】

二、string

1. 结构说明

Redis 最基础、最常用的数据结构,值可以是字符串、数字(整数 / 浮点数)、二进制数据(如图片、序列化对象),单个 String 最大支持 512MB。

特点:
字符数组,该字符串是动态字符串 raw,字符串长度小于1M 时,加倍扩容;超过 1M 每次只多扩1M;字符串最大长度为 512M;
(注意:redis 字符串是二进制安全字符串(通过len来判断结尾而非 '\0' );可以存储图片,二进制协议等二进制数据)

存储结构:字符串长度小于等于 20 且能转成整数,则使用 int 存储;字符串长度小于等于 44,则使用 embstr 存储;字符串长度大于 44,则使用 raw 存储;

2. 核心操作指令

指令语法格式指令说明
SET`SET key value [EX seconds] [PX milliseconds] [NX | XX]`
(EX、PX、NX、XX 顺序可以打乱)

设置键值对,可选参数:

- EX:设置过期时间(秒)

- PX:设置过期时间(毫秒)

- NX:仅当键不存在时才设置(用于分布式锁)

- XX:仅当键存在时才更新

GETGET key获取指定键的值,键不存在返回 nil
INCRINCR key对键的整数值进行原子自增 1,键不存在则先初始化为 0 再自增
DECRDECR key对键的整数值进行原子自减 1,键不存在则先初始化为 0 再自减
INCRBYINCRBY key increment原子自增指定数值(increment 可为正 / 负,等效于批量 INCR/DECR)
DECRBYDECRBY key decrement原子自减指定数值
SETEXSETEX key seconds value简化版:设置键值对并指定过期时间(秒),等效于 SET + EX
SETNXSETNX key value简化版:仅当键不存在时设置值,等效于 SET + NX
MSETMSET key1 value1 key2 value2 ...批量设置多个键值对,原子操作
MGETMGET key1 key2 ...批量获取多个键的值,提升查询效率(减少网络请求)

3. 典型应用场景

分布式锁

# 分布式锁 set lock uuid nx ex 30 # 保证锁的原子性设置和自动释放,避免死锁 # 释放锁 del lock if (get(lock) == uuid) del(lock)

临时有效数据:手机验证码、登录临时 token。

SETEX sms:138xxxx1234 300 "123456" # 5 分钟后自动过期

计数器系统(累加器):文章阅读量、视频播放量、接口调用次数。

INCR article:read:1001 # 每次访问自增 1

单值数据缓存:缓存商品详情、用户基本信息、首页热点数据。如果数据不常改动,可以设置多个属性(json格式)

SET role:10002 '{["name"]:"dcf",["sex"]:"male",["age"]:3}'

三、list

1. 结构说明

有序、可重复的元素集合,基于双向链表实现,两端操作(头部 / 尾部)性能极高,中间插入 / 删除性能较差,适合存储有序的序列数据。

特点:

双向链表实现,列表首尾操作(删除和增加)时间复杂度O(1) ;查找中间元素时间复杂度为
O(n) ;



存储结构:
列表中数据是否压缩的依据:元素长度小于 48,不压缩;元素压缩前后长度差不超过 8,不压缩;

2. 核心操作指令

指令语法格式指令说明
LPUSHLPUSH key value1 [value2 ...]从列表 ** 头部(左侧)** 插入一个 / 多个元素
RPUSHRPUSH key value1 [value2 ...]从列表 ** 尾部(右侧)** 插入一个 / 多个元素
LPOPLPOP key从列表头部弹出并删除一个元素,列表为空返回 nil
RPOPRPOP key从列表尾部弹出并删除一个元素,列表为空返回 nil
LRANGELRANGE key start stop获取列表中「start 到 stop」区间的元素(索引从 0 开始,stop=-1 表示获取所有元素)
LLENLLEN key获取列表的元素总个数
BRPOPBRPOP key [key2 ...] timeout阻塞式从列表尾部弹出元素(列表为空时,阻塞等待 timeout 秒,timeout=0 表示永久阻塞),适合消息队列
LREMLREM key count value删除列表中 count 个值为 value 的元素(count>0 从头部删,count<0 从尾部删,count=0 删除所有)
LTRIMLTRIM key start stop裁剪列表,仅保留「start 到 stop」区间的元素,删除其他元素(用于限制列表长度)

3. 典型应用场景

  1. 异步消息队列:操作与队列一样,但是在不同系统间;生成者和消费者;
  2. 分页查询(旧数据):对于无需复杂筛选的历史数据(如用户历史订单列表),可通过 LRANGE 实现简单分页(不适合高频更新、大数据量的分页场景)。

最新消息 / 动态列表:朋友圈动态、文章评论列表、系统通知列表。

RPUSH moments:1001 "动态1" "动态2" ltrim moments:1001 0 99 # 限制列表长度避免内存溢出 LRANGE moments:1001 0 9 # 获取最新 10 条动态

阻塞队列 (blocking queue):

LPUSH + BRPOP # 或者 RPUSH + BLPOP

队列 ( 先进先出FIFO)

LPUSH + RPOP # 或者 RPUSH + LPOP

栈(先进后出 FILO)

LPUSH + LPOP # 或者 RPUSH + RPOP

四、hash

1. 结构说明

用于存储键值对集合(类似 Java 中的 Map、Python 中的 dict),适合存储单个对象的多个属性,可单独操作对象的某个字段,无需修改整个对象。

特点:

散列表,在很多高级语言当中包含这种数据结构;c++ unordered_map 通过 key 快速索引
value;

存储结构:节点数量大于 512(hash-max-ziplist-entries) 或所有字符串长度大于 64(hash-max-ziplist-value),则使用 dict 实现;节点数量小于等于 512 且有一个字符串长度小于 64,则使用 ziplist 实现

2. 核心操作指令

指令语法格式指令说明
HSETHSET key field value [field2 value2 ...]给指定哈希表设置一个 / 多个字段 - 值对,字段不存在则新增,存在则更新
HGETHGET key field获取哈希表中指定字段的值
HMSETHMSET key field value [field2 value2 ...]批量设置哈希表字段(Redis 3.0 后可直接用 HSET 替代)
HMGETHMGET key field [field2 ...]批量获取哈希表中多个字段的值
HGETALLHGETALL key获取哈希表中所有字段和对应的值(返回键值对列表)
HDELHDEL key field [field2 ...]删除哈希表中一个 / 多个字段
HLENHLEN key获取哈希表中字段的总个数
HKEYSHKEYS key获取哈希表中所有字段名
HVALSHVALS key获取哈希表中所有字段对应的值
HEXISTSHEXISTS key field判断哈希表中指定字段是否存在,返回 1(存在)/ 0(不存在)

3. 典型应用场景

对比string存储json格式,hash存储的对象使用于频繁更改属性的场景

hmset user name dcf age 18 sex male # 与 string 比较 set string '{["name"]:"mark",["sex"]:"male",["age"]:18}' # 修改 # hash: hset user age 19 # string: get user # 将得到的字符串调用json解密,取出字段,修改 age 值 # 再调用json加密 set user '{["name"]:"dcf",["sex"]:"male",["age"]:19}'

对象数据存储:存储用户信息、商品属性、购物车功能、配置信息存储

# 对象数据存储:存储用户信息、商品属性 HSET user:1001 id 1001 name "张三" age 25 phone "138xxxx1234" HSET user:1001 age 26 # 可单独更新,无需修改整个用户对象)。 ​​​​​​​ # 购物车功能:以「用户 ID」为 Redis 键,「商品 ID」为 Hash 字段,「商品数量」为 Hash 值 HSET cart:1001 goods:1001 2 # 表示用户 1001 购物车中有 2 件商品 1001 HINCRBY cart:1001 goods:1001 1 # 实现商品数量加 1)。 # 配置信息存储:存储系统配置、应用参数 HSET config:app port 8080 timeout 30 log_level "info" # 方便单独查询和修改某个配置项)。

五、set

1. 结构说明

无序、不可重复的元素集合,基于哈希表实现,支持高效的去重和集合运算(交集、并集、差集),单个元素最大支持 512MB。

特点:集合;用来存储唯一性字段,不要求有序;存储不需要有序,操作(交并差集的时候排序)



存储结构:元素都为整数且节点数量小于等于 512(set-max-intset-entries),则使用整数数组存储;元素当中有一个不是整数或者节点数量大于 512,则使用字典存储

2. 核心操作指令

指令语法格式指令说明
SADDSADD key member1 [member2 ...]向集合中添加一个 / 多个元素,重复元素自动去重
SMEMBERSSMEMBERS key获取集合中所有元素(无序返回)
SISMEMBERSISMEMBER key member判断元素是否在集合中,返回 1(存在)/ 0(不存在)
SREMSREM key member1 [member2 ...]从集合中删除一个 / 多个元素
SCARDSCARD key获取集合中元素的总个数
SINTERSINTER key1 [key2 ...]获取多个集合的交集(所有集合中都存在的元素)
SUNIONSUNION key1 [key2 ...]获取多个集合的并集(所有集合中的不重复元素)
SDIFFSDIFF key1 [key2 ...]获取多个集合的差集(在 key1 中存在,在其他集合中不存在的元素)
SRANDMEMBERSRANDMEMBER key [count]从集合中随机获取 count 个元素(不删除元素,count 缺省为 1)
SPOPSPOP key [count]从集合中随机弹出并删除 count 个元素

3. 典型应用场景

随机抽奖系统:幸运大转盘、抽奖活动。

SADD lottery:2026 1001 1002 ..., SPOP lottery:2026 3 # 随机抽取 3 名中奖用户

社交关系计算:共同好友、推荐好友、共同兴趣标签。

SINTER user:friends:1001 user:friends:1002 # 获取用户 1001 和 1002 的共同好友 SUNION user:friends:1001 user:friends:1002 # 获取用户的所有好友列表。 SDIFF user:friends:1001 user:friends:1002 # 用户 1002 可能想认识的人

数据去重:用户点赞列表、文章收藏列表、签到记录去重、黑白名单系统

SADD article:like:1001 1001 1002 # 避免同一用户重复点赞 SISMEMBER article:like:1001 1002 # 判断用户是否已点赞 SADD blacklist:user 1003 # 接口请求时通过 SISMEMBER 判断用户是否在黑名单中)。

六、zset

1. 结构说明

有序、不可重复的元素集合,每个元素关联一个浮点型分数(score),Redis 按 score 从小到大排序(可反向排序),支持按 score 范围和排名查询,兼顾了 Set 的去重特性和 List 的有序特性。

特点:

有序集合;用来实现排行榜;它是一个有序唯一;

存储结构:节点数量大于 128 或者有一个字符串长度大于 64,则使用跳表(skiplist);节点数量小于等于 128(zset-max-ziplist-entries)且所有字符串长度小于等于 64(zset-max-ziplist-value),则使用 ziplist 存储;


复杂度:数据少的时候,节省空间; O(n)数量多的时候,访问性能;O(1) or O(log_{2}{n})

2. 核心操作指令

指令语法格式指令说明
ZADDZADD key score1 member1 [score2 member2 ...]向有序集合中添加一个 / 多个元素,score 为排序依据,重复 member 会更新其 score
ZRANGEZRANGE key start stop [WITHSCORES]按 score从小到大获取「start 到 stop」区间的元素,WITHSCORES 同时返回元素和对应的 score
ZREVRANGEZREVRANGE key start stop [WITHSCORES]按 score从大到小获取区间元素(适合排行榜倒序查询)
ZRANGEBYSCOREZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]按 score 范围获取元素(min/max 可使用 ( 表示开区间,如 (100 表示大于 100)
ZINCRBYZINCRBY key increment member给指定元素的 score 原子增减指定数值(increment 可为正 / 负)
ZREMZREM key member1 [member2 ...]从有序集合中删除一个 / 多个元素
ZCARDZCARD key获取有序集合中元素的总个数
ZSCOREZSCORE key member获取指定元素对应的 score 值
ZRANKZRANK key member获取指定元素的排名(从小到大,排名从 0 开始)
ZREVRANKZREVRANK key member获取指定元素的排名(从大到小,排名从 0 开始)

3. 典型应用场景

时间窗口限流:
系统限定用户的某个行为在指定的时间范围内(动态)只能发生 N 次;

# 指定用户 user_id 的某个行为 action 在特定时间内 period 只允许发生该行为做大次数 max_count local function is_action_allowed(red, userid, action, period, max_count) local key = tab_concat({"hist", userid, action}, ":") local now = zv.time() red:init_pipeline() -- 记录行为 red:zadd(key, now, now) -- 移除时间窗口之前的行为记录,剩下的都是时间窗口内的记录 red:zremrangebyscore(key, 0, now - period *100) -- 获取时间窗口内的行为数量 red:zcard(key) -- 设置过期时间,避免冷用户持续占用内存 时间窗口的长度+1秒 red:expire(key, period + 1) local res = red:commit_pipeline() return res[3] <= max_count end # 维护一次时间窗口,将窗口外的记录全部清理掉,只保留窗口内的记录; # 缺点:记录了所有时间窗口内的数据,如果这个量很大,不适合做这样的限流;漏斗限流 # 注意:如果用 key + expire 操作也能实现,但是实现的是熔断限流,这里是时间窗口限流的功能; 

分布式定时器:
生产者将定时任务 hash 到不同的 redis 实体中,为每一个 redis 实体分配一个 dispatcher 进程,用来定时获取 redis 中超时事件并发布到不同的消费者中;




 

延时队列:将任务的执行时间戳作为 score,消费者定期通过 ZRANGEBYSCORE 获取当前时间之前的任务执行。

ZADD delay:queue 1735660800 task:1001 # 表示任务 1001 在 2025-01-01 00:00 执行)。

各类排行榜系统:销量榜、积分榜、热度榜、游戏天梯榜

ZADD goods:sales 100 goods:1001 200 goods:1002 ZREVRANGE goods:sales 0 9 WITHSCORES # 获取销量前 10 商品; ZINCRBY goods:sales 1 goods:1001 # 实现销量加 1

七、常用扩展数据结构

1. 位图(Bitmap)

1.1 结构说明

并非独立数据结构,基于 String 实现,按「位」存储数据,每个位只能是 0 或 1,极大节省内存空间(1 个字节 = 8 位,可存储 8 个状态)。

1.2 核心操作指令

指令语法格式指令说明
SETBITSETBIT key offset value设置指定偏移量(offset,从 0 开始)的位值(0/1)
GETBITGETBIT key offset获取指定偏移量的位值
BITCOUNTBITCOUNT key [start end]统计位图中 1 的个数(start/end 为字节索引,可选)
BITOPBITOP operation destkey key1 [key2 ...]位图运算(AND/OR/XOR/NOT),结果存入 destkey

1.3 典型应用场景

  • 批量状态判断(如判断用户是否领取过某类优惠券,1 表示已领取,0 表示未领取)。

活跃度统计

# 查询用户1001是否当月有活跃 BITOP OR user:active:202601 user:active:20260101 user:active:20260102 # 合并所有日期 GETBIT user:active:202601 1001 # 1=有活跃,0=无活跃 # 2. 查询用户1001是否当月满勤 BITOP AND user:full:202601 user:active:20260101 user:active:20260102 # 合并所有日期 GETBIT user:full:202601 1001 # 1=满勤,0=有缺勤

用户签到系统

SETBIT user:sign:1001 0 1 # 表示用户 1001 第 1 天签到 BITCOUNT user:sign:1001 # 统计当月签到天数

2. 地理空间(Geo)

2.1 结构说明

并非独立数据结构,基于 ZSet 实现,用于存储经纬度坐标,支持距离计算、附近地点查询等地理空间操作。

2.2 核心操作指令

简略:

指令语法格式指令说明
GEOADDGEOADD key longitude latitude member [lon2 lat2 member2 ...]添加地理位置(经度、纬度、地点名称)
GEOPOSGEOPOS key member1 [member2 ...]获取指定地点的经纬度坐标
GEODISTGEODIST key member1 member2 [unit]计算两个地点之间的距离(unit 可选:m 米、km 千米,默认 m)
GEORADIUSGEORADIUS key longitude latitude radius unit [WITHDIST] [WITHCOORD]根据指定经纬度,查询半径范围内的地点(WITHDIST 返回距离,WITHCOORD 返回坐标)
GEOSEARCH`GEOSEARCH key FROMMEMBER member BYRADIUS radius unit [ASC | DESC]`根据指定地点,查询半径范围内的地点(Redis 6.2+ 支持,更易用)


详尽:

指令语法格式指令说明
GEOADDGEOADD key longitude latitude member [lon2 lat2 member2 ...]

添加地理位置(经度、纬度、地点名称)

・限制:经度范围-180~180,纬度范围-85.05112878~85.05112878(超出会报错)

・返回值:成功添加的member数量

GEOPOSGEOPOS key member1 [member2 ...]

获取指定地点的经纬度坐标

・返回值:每个member对应[经度, 纬度]数组;不存在的member返回nil

GEODISTGEODIST key member1 member2 [unit]

计算两个地点之间的距离

unit可选值:m(米,默认)、km(千米)、mi(英里)、ft(英尺)


• 返回值:距离字符串(如"1.5210");任意member不存在则返回nil

GEORADIUS`GEORADIUS key longitude latitude radius unit [WITHDIST] [WITHCOORD] [WITHHASH] [COUNT count] [ASC | DESC]`

根据指定经纬度,查询半径范围内的地点

・附加参数:

- WITHDIST:返回地点与中心的距离

- WITHCOORD:返回地点的经纬度

- WITHHASH:返回地点的 52 位 GeoHash 值

- COUNT count:限制返回结果的数量

- ASC/DESC:按距离「由近到远 / 由远到近」排序

GEOSEARCH`GEOSEARCH key [FROMMEMBER member | FROMLONLAT lon lat] [BYRADIUS radius unit | BYBOX width height unit] [WITHDIST] [WITHCOORD] [WITHHASH] [COUNT count] [ASC | DESC]`

灵活查询地理范围(Redis 6.2 + 支持)
・范围中心:
- FROMMEMBER:以已有地点为中心
- FROMLONLAT:以指定经纬度为中心

・范围形状:
- BYRADIUS:圆形半径范围
- BYBOX:矩形范围(宽度、高度为边长)
・附加参数同GEORADIUS

GEOSEARCHSTORE`GEOSEARCHSTORE destkey sourcekey [FROMMEMBER member
FROMLONLAT lon lat] [BYRADIUS radius unitBYBOX width height unit] [COUNT count] [ASCDESC]`

GEOSEARCH的查询结果存储到destkey(类型为 ZSet)

・返回值:成功存储的地点数量

・用途:批量查询后持久化结果,便于后续二次处理

补充说明:GEORADIUS是旧版指令(Redis <6.2),GEOSEARCH是新版替代指令(更推荐);单位支持m(米)、km(公里)、mi(英里)、ft(英尺);WITHDIST会返回距离数值,ASC表示按距离由近到远排序(DESC是由远到近)。

2.3 典型应用场景

配送范围判断(如判断用户是否在商家的配送范围内,通过 GEODIST 计算距离是否小于配送阈值)。

# 添加外卖商家到key `store:location`(经度 纬度 商家ID) GEOADD store:location 116.3956 39.9299 "商家1" # 北京王府井附近 GEOADD store:location 116.4100 39.9100 "商家2" # 北京东单附近 GEOADD store:location 116.4300 39.9000 "商家3" # 北京国贸附近(距离中心>3公里) # 假设 “商家 1 的配送范围是 2 公里”,计算用户(116.40 39.90)到商家 1 的距离, # 判断是否≤2 公里: # 指令:GEODIST key 成员1 成员2 单位 GEODIST store:location "商家1" 116.40 39.90 km

地理位置排序(如旅游平台按距离远近排序景点、酒店)。

# 添加旅游景点到key `scenic:location` GEOADD scenic:location 116.3972 39.9165 "故宫" # 北京故宫 GEOADD scenic:location 116.4038 39.9240 "天安门" # 北京天安门 GEOADD scenic:location 116.4810 39.9128 "颐和园" # 北京颐和园(距离中心较远) # 以 “用户位置(116.40 39.90)” 为中心,查 5 公里内的景点,按距离由近到远排序 # Redis 6.2+推荐用GEOSEARCH(更灵活):按成员为中心查询 GEOSEARCH scenic:location FROMLONLAT 116.40 39.90 BYRADIUS 5 km WITHDIST ASC

附近的人 / 门店

# 添加外卖商家到key `store:location`(经度 纬度 商家ID) GEOADD store:location 116.3956 39.9299 "商家1" # 北京王府井附近 GEOADD store:location 116.4100 39.9100 "商家2" # 北京东单附近 GEOADD store:location 116.4300 39.9000 "商家3" # 北京国贸附近(距离中心>3公里) # 以 “用户位置(116.40 39.90,北京建国门附近)” 为中心, # 查 3 公里内的商家,显示距离 + 按距离由近到远排序: GEORADIUS store:location 116.40 39.90 3 km WITHDIST ASC

八、查找Key

Redis 中用于查找 / 列出 key 的核心命令主要是 KEYSSCAN,其中 SCAN 是更推荐在生产环境使用的方式。下面我会详细介绍这些命令的用法、区别和最佳实践。

1. KEYS 命令(简单但不推荐生产使用)

KEYS 是最基础的查找 key 的命令,支持通配符匹配,但会阻塞 Redis 主线程,在数据量大时可能导致服务卡顿,因此仅建议在开发 / 调试环境使用。

语法

KEYS pattern 

通配符规则

  • *:匹配任意数量的任意字符(包括 0 个)
  • ?:匹配单个任意字符
  • []:匹配括号内的单个字符(如 [abc] 匹配 a、b 或 c)
  • \:转义特殊字符

示例

# 列出所有 key KEYS * # 列出以 "user:" 开头的所有 key KEYS user:* # 列出以 "order" 结尾的所有 key KEYS *order # 列出第二个字符是 "a" 的 key(如 "ka1", "ba2") KEYS ?a* # 列出以 "prod" 开头且第三个字符是 1 或 2 的 key(如 "prod1", "prod2") KEYS prod[12]* 

2. SCAN 命令(生产环境推荐)

SCAN 是迭代式查找 key 的命令,非阻塞(分批返回结果),适合在生产环境遍历大量 key,避免阻塞 Redis。

语法

SCAN cursor [MATCH pattern] [COUNT count] [TYPE type] 

参数说明

  • cursor:游标,初始值为 0,每次返回结果会包含下一个游标,直到返回 0 表示遍历完成
  • MATCH pattern:可选,通配符匹配规则(同 KEYS)
  • COUNT count:可选,指定每次迭代返回的 key 数量(非精确值,默认 10)
  • TYPE type:可选,按数据类型过滤(如 string、hash、list、set、zset)

示例

# 初始迭代(游标 0),匹配所有 key,每次返回约 20 个 SCAN 0 MATCH * COUNT 20 # 迭代以 "user:" 开头的 key,按类型过滤为 hash SCAN 0 MATCH user:* TYPE hash # 假设第一次返回游标 50,继续迭代 SCAN 50 MATCH user:* TYPE hash 

返回结果示例

1) "50" # 下一个游标 2) 1) "user:1001" 2) "user:1002" 3) "user:1003" 

3. 辅助命令

TYPE:查看指定 key 的数据类型(配合查找结果使用)

TYPE user:1001 

EXISTS:检查指定 key 是否存在(可批量检查)

EXISTS key1 key2 # 返回存在的 key 数量 

DBSIZE:快速获取当前数据库的 key 总数(无需遍历,性能极高)

DBSIZE 

4. 使用建议

  • 开发 / 调试环境:可临时使用 KEYS,操作简单。
  • 生产环境:必须使用 SCAN,避免阻塞主线程;如果需要统计 key 总数,优先用 DBSIZE 而非 KEYS *
  • 通配符优化:尽量缩小匹配范围(如 user:* 而非 *),减少迭代次数。
  • 集群环境KEYS/SCAN 仅作用于当前连接的节点,如需遍历整个集群,需逐个节点执行。

5. 总结

  • Redis 查找 key 的核心命令是 KEYS(简单但阻塞)和 SCAN(非阻塞,生产推荐),均支持通配符匹配。
  • SCAN 通过游标分批迭代,搭配 MATCH/TYPE/COUNT 参数可精准过滤 key,避免服务卡顿。
  • 辅助命令 DBSIZE/EXISTS/TYPE 可配合查找操作,提升效率和准确性。

九、细节补充

1. key的设计

单一功能一个key:取有意义的就行相同功能多个key:以" : "作为分割
(tips:为什么使用冒号,业内常用,界面客户端的工具也常用:来表示子目录)

2. 怎么删除key

del key:删除该键值对当value为空的时候,会自动移除该key

3. 怎么创建key

添加的时候,如果不存在key,那么redis会自动创建

4. 业务中常用组合数据结构

hash 的 value 存放 list/set/zet 的 keyhash + listhash + sethash + zet

    Read more

    人工智能算法框架 EasyAI:让 Java 程序员用 Java 的方式做 AI

    人工智能算法框架 EasyAI:让 Java 程序员用 Java 的方式做 AI

    不少 Java 小伙伴私下跟我吐槽:现在 AI 这么火,咱们写 Java 的是不是注定只能在旁边看戏? 说实话,以前确实挺憋屈的。主流 AI 框架全是 Python 的天下(TensorFlow、PyTorch 等),咱们想入个门,不仅要跨过语言鸿沟,还得去趟 CUDA、cuDNN 这种“环境配置地狱”。配环境的时间比写代码还长,这种生态割裂感真的让人头大 。 EasyAI 的出现正是为了打破这一僵局。它是一个由 Dromara 开源社区维护的纯 Java 实现的人工智能框架,主打零依赖、开箱即用,旨在让 Java 程序员能用自己最熟悉的语言开发 AI 应用 。 注意:EasyAI 和 Spring AI 两者不是同一类东西,解决的问题不一样,后面会提到。

    By Ne0inhk
    Spring AI :Java 生态原生 AI 框架入门指南

    Spring AI :Java 生态原生 AI 框架入门指南

    在大模型席卷全球的技术浪潮下,Java 开发者们迫切需要一款贴合自身生态、低门槛接入 AI 能力的框架。Spring AI 的出现,恰好填补了这一空白 —— 它并非简单移植 Python 生态的现有方案,而是深度遵循 Spring 设计哲学,为 Java 和 Spring 开发者打造了原生的 AI 开发框架。本文将从 Spring AI 的核心概念、核心特性出发,结合实际环境搭建与首个对话案例,带大家快速上手这款框架,解锁 Java 生态与 AI 融合的全新可能。 一、什么是 Spring AI? Spring AI 是面向 Java 和 Spring 生态的原生人工智能框架,其核心设计理念完全传承自 Spring:依赖注入、POJO

    By Ne0inhk
    66个JAVA常见代码大全:学完这篇从Java小白到AI全栈架构师

    66个JAVA常见代码大全:学完这篇从Java小白到AI全栈架构师

    66个JAVA常见代码大全:学完这篇从Java小白到AI全栈架构师 摘要:本文详细列举了 66 个 Java 编程中的关键代码示例,包括基础语法、数据类型、条件判断、循环、数组、方法、面向对象、继承、接口、抽象类、多态、封装、静态变量、内部类、匿名类、泛型、集合框架、异常处理、文件 I/O、多线程、同步以及高级并发概念,帮助你从入门到成长为架构师。 66个Java常见代码大全:学完这篇从Java小白到AI全栈架构师 引言 在当今的编程世界中,Java 作为一种广泛使用的编程语言,涵盖了从基础语法到复杂架构的方方面面。无论是刚接触编程的新手,还是经验丰富的开发者,掌握Java的核心技术和常用模式,都是成为一名高效开发者的必经之路。本篇文章将带您通过 66 个关键代码示例,从零开始深入学习 Java,从最基础的语法到高阶的并发编程,帮助您成为一名合格的

    By Ne0inhk
    Spring AI:Java 生态的 AI 赋能革命,企业级智能应用新标杆

    Spring AI:Java 生态的 AI 赋能革命,企业级智能应用新标杆

    目录 一、核心定位:不止是框架,更是生态连接器 二、核心架构与关键能力:简化复杂 AI 应用构建 1. 对话交互核心:ChatClient 2. 语义理解基础:EmbeddingClient 与 VectorStore 3. 提示工程利器:PromptTemplate 4. 1.1 版本核心突破 三、典型场景落地:赋能全行业智能升级 四、未来展望:Java 生态的 AI 普及之路 当生成式 AI 与大型语言模型(LLMs)重塑软件开发范式,如何让 AI 能力无缝融入成熟的企业级技术体系,成为全球开发者面临的核心命题。Spring AI 的横空出世,为 Java 生态带来了颠覆性解决方案 —— 它以

    By Ne0inhk