写在前面掌握Redis的数据类型是使用Redis的基础。不同的数据类型适用于不同的业务场景选对类型能让你的系统性能翻倍。今天我们来全面了解Redis的5种基本数据类型。文章目录写在前面一、5种基本数据类型概述二、String字符串类型2.1 String的特点2.2 基本命令示例2.3 适用场景三、Hash哈希类型3.1 Hash的特点3.2 基本命令示例3.3 适用场景四、List列表类型4.1 List的特点4.2 基本命令示例4.3 适用场景五、Set集合类型5.1 Set的特点5.2 基本命令示例5.3 适用场景六、ZSet有序集合类型6.1 ZSet的特点6.2 基本命令示例6.3 适用场景七、数据类型选择对比表八、踩坑提醒大key问题什么是大key大key的危害如何发现大key如何处理大key九、面试高频考点Q1Redis的五种数据类型底层实现是什么Q2为什么Redis用跳表而不是红黑树实现ZSetQ3如何选择数据类型十、参考资料十一、互动话题一、5种基本数据类型概述实际场景选择合适的数据类型就像选择合适的工具能让你的开发事半功倍。Redis提供了5种基本数据类型每种类型都有其独特的特点和适用场景。数据类型底层实现特点典型应用StringSDS简单动态字符串最基础类型可存字符串、整数、浮点数缓存、计数器、分布式锁Hash哈希表压缩列表键值对集合适合存储对象用户信息、商品详情List双向链表压缩列表有序可重复支持两端操作消息队列、最新列表Set哈希表整数集合无序不重复支持集合运算标签、共同好友ZSet跳表哈希表有序不重复带分数排序排行榜、延时队列二、String字符串类型2.1 String的特点经验之谈String是最灵活的类型但不要什么都往String里塞该用Hash的时候别省。String是Redis最基本的数据类型可以存储字符串整数浮点数二进制数据如图片、序列化对象底层实现使用SDSSimple Dynamic String相比C字符串有以下优势O(1)获取长度防止缓冲区溢出减少内存重分配次数二进制安全2.2 基本命令示例# 设置值 set user:1 zhangsan # 获取值 get user:1 # 设置值并设置过期时间秒 setex session:abc 3600 user_data # 仅当键不存在时设置 setnx lock:order 1 # 批量设置 mset key1 value1 key2 value2 # 批量获取 mget key1 key2 # 数值操作 incr counter incrby counter 10 decr counter上述命令中SETEX同时设置值和过期时间适合缓存场景SETNX实现分布式锁的基础MSET/MGET批量操作提升效率。2.3 适用场景场景实现方式示例缓存SET/GET缓存用户信息、商品详情计数器INCR/INCRBY文章阅读量、点赞数分布式锁SETNX防止重复下单分布式IDINCR生成唯一IDSession共享SETEX集群环境会话管理三、Hash哈希类型3.1 Hash的特点踩坑提醒Hash适合存储对象但如果字段很多且经常变动要考虑内存占用。Hash是一个键值对集合特别适合存储对象。相比将对象JSON序列化后存为String对比项Hash存储String存储内存占用较小ziplist编码时较大部分更新支持HSET单字段需要整体更新部分读取支持HGET单字段需要整体读取适用场景字段较多、需部分访问字段少、整体读写3.2 基本命令示例# 设置单个字段 hset user:1 name zhangsan # 设置多个字段 hmset user:1 name zhangsan age 25 city beijing # 获取单个字段 hget user:1 name # 获取多个字段 hmget user:1 name age # 获取所有字段和值 hgetall user:1 # 获取所有字段名 hkeys user:1 # 获取所有值 hvals user:1 # 删除字段 hdel user:1 city # 字段数值增减 hincrby user:1 age 1 # 检查字段是否存在 hexists user:1 name3.3 适用场景用户信息存储用户ID为key各属性为field商品信息商品ID为key名称、价格、库存等为field购物车用户ID为key商品ID为field数量为value四、List列表类型4.1 List的特点实际场景List天生就是为队列设计的LPUSHRPOP就是简单的消息队列。List是一个双向链表支持从两端插入和弹出有序元素按插入顺序排列可重复允许重复元素双向操作支持左右两端操作底层实现元素少时使用ziplist压缩列表元素多时使用quicklist双向链表4.2 基本命令示例# 左侧插入 lpush queue:task task1 # 右侧插入 rpush queue:task task2 # 左侧弹出 lpop queue:task # 右侧弹出 rpop queue:task # 获取列表长度 llen queue:task # 获取指定范围元素 lrange queue:task 0 -1 # 阻塞弹出用于消息队列 blpop queue:task 30 # 通过索引获取元素 lindex queue:task 0 # 设置指定索引的值 lset queue:task 0 new_task注意事项LRANGE的索引从0开始-1表示最后一个元素BLPOP是阻塞操作会一直等待直到有元素或超时4.3 适用场景场景命令组合说明消息队列LPUSH BRPOP异步任务处理最新列表LPUSH LRANGE最新文章、最新评论时间线LPUSH LTRIM保留最近N条记录五、Set集合类型5.1 Set的特点经验之谈Set的集合运算交集、并集、差集是它的杀手锏功能用好了能省很多代码。Set是无序、不重复的字符串集合无序元素没有固定顺序不重复自动去重支持集合运算交集、并集、差集底层实现元素少且都是整数时使用intset否则使用hashtable5.2 基本命令示例# 添加元素 sadd tags:article:1 redis database nosql # 获取所有元素 smembers tags:article:1 # 检查元素是否存在 sismember tags:article:1 redis # 移除元素 srem tags:article:1 nosql # 获取集合大小 scard tags:article:1 # 随机获取元素 srandmember tags:article:1 # 随机弹出元素 spop tags:article:1 # 交集 sinter tags:article:1 tags:article:2 # 并集 sunion tags:article:1 tags:article:2 # 差集 sdiff tags:article:1 tags:article:25.3 适用场景场景实现方式示例标签系统SADD/SMEMBERS文章标签、用户标签共同好友SINTER社交推荐唯一性判断SADD返回值投票去重、签到统计抽奖系统SPOP/SRANDMEMBER随机抽取用户六、ZSet有序集合类型6.1 ZSet的特点踩坑提醒ZSet功能强大但内存占用较高数据量大时要权衡使用。ZSet是有序、不重复的字符串集合每个元素关联一个分数score有序按分数排序不重复元素唯一可按分数范围查询底层实现使用skiplist跳表 hashtable跳表保证有序和范围查询效率哈希表保证O(1)查找6.2 基本命令示例# 添加元素 zadd leaderboard 100 user1 zadd leaderboard 200 user2 150 user3 # 获取元素分数 zscore leaderboard user1 # 获取排名从0开始升序 zrank leaderboard user1 # 获取排名降序 zrevrank leaderboard user1 # 获取指定范围元素按分数 zrangebyscore leaderboard 100 200 # 获取指定排名范围元素 zrange leaderboard 0 9 withscores # 获取降序排名范围 zrevrange leaderboard 0 9 withscores # 增加分数 zincrby leaderboard 50 user1 # 移除元素 zrem leaderboard user1 # 获取集合大小 zcard leaderboard # 统计分数范围内的元素数量 zcount leaderboard 100 2006.3 适用场景场景实现方式示例排行榜ZADD ZREVRANGE游戏积分榜、热搜榜延时队列分数为执行时间戳定时任务调度带权重的标签分数为权重标签推荐系统范围查询ZRANGEBYSCORE按时间范围查询七、数据类型选择对比表需求场景推荐类型理由简单缓存String简单直接性能最优对象存储Hash支持部分读写内存效率高队列/栈List天然支持两端操作去重集合Set自动去重支持集合运算排序需求ZSet自动排序支持范围查询计数器StringINCR原子操作时间线List/ZSetList简单ZSet支持按时间范围查询八、踩坑提醒大key问题踩坑提醒大key是Redis性能杀手务必重视什么是大keyString类型value超过10KB集合类型元素数量超过5000个大key的危害内存不均衡导致主从同步延迟阻塞操作删除大key会阻塞Redis网络拥塞传输大key占用带宽如何发现大key# 使用redis-cli扫描redis-cli--bigkeys# 使用memory命令memory usage keyname如何处理大key拆分将大key拆分为多个小key本地缓存大value考虑本地缓存异步删除使用UNLINK替代DEL九、面试高频考点Q1Redis的五种数据类型底层实现是什么答案StringSDS简单动态字符串Hashziplist hashtableListquicklistziplist linkedlistSetintset hashtableZSetziplist skiplist hashtableQ2为什么Redis用跳表而不是红黑树实现ZSet答案跳表实现更简单易于调试和维护跳表支持范围查询更高效跳表内存占用与红黑树相当跳表并发操作更容易实现Q3如何选择数据类型答案根据业务需求选择简单KV存储用String对象存储用Hash队列用List去重用Set排序用ZSet同时考虑内存占用和访问效率十、参考资料Redis数据类型官方文档十一、互动话题你在实际项目中用过哪些Redis数据类型有没有遇到过选型错误导致的性能问题欢迎在评论区分享你的经验下一篇我们将深入探讨String和Hash的详细命令与应用场景。