【redis】数据结构及操作命令

发布于:2025-06-21 ⋅ 阅读:(22) ⋅ 点赞:(0)

Redis数据类型及操作命令

概述

5种基础数据类型:String、List、Set、Zset、Hash

3种特殊数据类型:

  • geospatial(地理空间的),底层是Zset
  • hyperloglog:(基数==不重复的元素)
  • bitmaps:(位存储)

Stream 类型:
Redis5.0 中还增加了一个数据结构Stream,它借鉴了Kafka的设计,是一个新的强大的支持多播的可持久化的消息队列。

详述

  1. String (字符串)

    • 描述: 最基本的数据类型。一个 Key 对应一个 Value。Value 不仅是文本字符串,也可以是数字(整数或浮点数)或二进制数据(如图片、序列化对象)。

    • 特点:

      • 最大容量:512 MB。

      • 可以对数字执行原子操作:INCRDECRINCRBYDECRFLOAT 等。

      • 支持部分字符串操作:APPENDGETRANGESETRANGESTRLEN

      • 支持位操作:SETBITGETBITBITCOUNTBITOP(位图功能)。

    • 常见用途:

      • 缓存 HTML 片段、JSON 数据、序列化对象。

      • 计数器(网页访问量、点赞数)。

      • 分布式锁(配合 SET key value NX PX milliseconds)。

      • 位图(用户签到、布隆过滤器基础)。

    • 命令:

      select 6:切换数据库

      Dbsize:查看数据库的大小

      Keys *:查看所有的key

      Flushdb:清空当前数据库

      Flushall:清空所有数据库

      Set name guoqi:设置一个key,值为guoqi

      Setex(set with expire)

      Setex name 30 “guoqi”:设置name30s后过期,值为guoqi

      Get name:得到该数据库key值为name的value值

      Get age:得到该数据库key值为age的value值

      Exits name:若数据库中存在key值为name,返回1,否则返回0

      Expire name 10:让数据库中key值为name的value值10秒钟过期

      Ttl name:查看当前key的剩余时间

      Type name:查看当前key是什么类型

      Append name “123“:往key值为name的字符串后面加上”123”,返回值是字符串的长度

      strlen name:返回value值的长度

      del key : 删除key

      SETNX key value :如果可以不存在则设置

      SETEX key seconds value:如果可以不存在则设置(seconds是过期时间,秒为单位),如果 key 已经存在,setex命令将覆写旧值。

  2. List (列表)

    • 描述: 一个有序的字符串集合,按照插入顺序排序。你可以从列表的两端添加或移除元素。

    • 特点:

      • 双向链表实现(底层是 quicklist)。

      • 支持在头部(Left)和尾部(Right)高效插入/删除:LPUSHRPUSHLPOPRPOP

      • 支持范围查询:LRANGE

      • 支持阻塞操作:BLPOPBRPOP(用于简单的消息队列)。

      • 可以修剪列表:LTRIM

      • 最大元素数:2^32 - 1 (约 40 亿)。

    • 常见用途:

      • 消息队列(FIFO 用 LPUSH/RPOP 或 RPUSH/LPOP,配合阻塞操作更好)。

      • 最新消息/动态列表(如最新 10 条微博,用 LPUSH + LTRIM)。

      • 记录操作日志。

    • 命令:

      Lpush list one 将一个或多个值放到列表头部(后插入的放在最前面)

      Rpush list two 将一个或多个值放到列表尾部

      Lrange list 0 -1 输出集合中的全部值

      Lpop list 弹出(移除)顶部值

      Rpop list 弹出(移除)底部值

      Lindex list 0 获取下标为0的值

      Lindex list 1 获取下标为1的值

      Llen list 获取list的长度

      Lrem list 2 one 移除list中的两个one(lrem  key  数量  元素值  移除队列中多少个 值为xxx的元素)

      Ltrim mylist 1 2 通过下标截取指定的长度,这个list已经被截断了,只剩下了截取的部分lset list 0 value2 把list的第0个位置的值更新为value2,若该位置无值,则会报错

      Linsert list before “one” “two” 在list的one之前插入two

      注意:

      当队列中没有消息时,会删除队列的key。

  3. Hash (哈希表 / 字典)

    • 描述: 一个键值对集合,特别适合存储对象(如用户信息、产品信息)。

    • 特点:

      • 一个 Key 对应一个 field-value 映射表。

      • 可以高效地操作单个字段:HSETHGETHDELHEXISTS

      • 支持批量操作:HMSETHMGETHGETALL

      • 支持对数值字段进行原子增减:HINCRBYHINCRBYFLOAT

      • 可以获取所有字段名或字段值:HKEYSHVALS

      • 最大字段数:2^32 - 1 (约 40 亿)。

    • 常见用途:

      • 存储对象(用户信息:user:1000 {name: "Alice", age: 30, email: "alice@example.com"})。

      • 存储具有多个属性的实体。

      • 聚合数据(避免序列化/反序列化整个对象)。

    • 命令:

      Map集合,key-map   === key-<k-v>

      Hset myhash k1 v1 往myhash集合里放值,key是k1,value是v1

      Hget myhash k1 通过k1得到对应的value值

      Hmset myhash k1 v1 k2 v2 一次设置多个k-v键值对

      Hmget myhash k1 k2 一次得到多个value值

      Hgetall myhash 得到全部的数据(全部的key和全部的value,输出方式为 一个key,一个value)

      Hdel myhash k1 删除指定的key,对应的value值也会被删除

      Hlen myhash 获取hash表的键值对个数

      Hexists myhash k1 查看myhash中k1存不存在

      Hkeys myhash 只获取所有的key

      Hvals myhash 只获取所有的value

  4. Set (集合)

    • 描述: 一个无序的、唯一的字符串集合。集合成员不允许重复。

    • 特点:

      • 高效的添加、删除、检查成员是否存在:SADDSREMSISMEMBER

      • 支持集合运算:SINTER (交集), SUNION (并集), SDIFF (差集)。

      • 支持获取所有成员:SMEMBERS (谨慎使用,大数据量可能阻塞)。

      • 支持随机获取成员:SRANDMEMBERSPOP

      • 支持获取集合大小:SCARD

      • 最大成员数:2^32 - 1 (约 40 亿)。

    • 常见用途:

      • 标签系统(文章的标签)。

      • 唯一性保证(某用户点赞过的文章 ID)。

      • 共同好友/兴趣(求交集)。

      • 随机抽取(抽奖)。

      • 数据去重。

    • 命令:

      不允许出现重复的值,并且插入的值都是无序的

      Sadd myset hello 往集合中加入值

      Smembers myset 查看集合中的全部成员

      Sismembers myset hello 查看hello是否是集合中的成员,是返回1

      Scard myset 查看集合中的元素个数

      Srem myset hello 移除集合中的指定元素

      srandmember myset 随机抽取集合中的一个元素

      srandmember myset 2 随机抽取集合中的两个元素

      spop myset 随机删除集合中的元素

      SDIFF set1 set2 取set1和set2的差集

      SINTER set1 set2 取set1和set2的交集(共同好友就是这样实现的)

      SUNION set1 set2 取set1和set2的并集

  5. Sorted Set (有序集合 / ZSet)

    • 描述: 类似于 Set,但每个成员都关联一个分数 (score),成员按分数排序(默认升序)。分数可以重复,但成员唯一。

    • 特点:

      • 通过分数进行范围查询:ZRANGEBYSCOREZREVRANGEBYSCORE

      • 通过排名(位置)进行查询:ZRANGEZREVRANGE (支持 WITHSCORES)。

      • 高效添加、删除、更新分数:ZADD (可更新分数), ZREM

      • 支持获取成员排名:ZRANKZREVRANK

      • 支持获取成员分数:ZSCORE

      • 支持集合运算(按分数聚合):ZUNIONSTOREZINTERSTORE

      • 支持获取集合大小:ZCARD

      • 支持按分数范围统计数量:ZCOUNT

      • 最大成员数:2^32 - 1 (约 40 亿)。

    • 常见用途:

      • 排行榜(按分数排序)。

      • 带权重的消息队列(分数代表优先级或执行时间)。

      • 范围查找(时间线、价格区间)。

      • 唯一计数器(成员作为计数器名称,分数作为计数值)。

    • 命令:

      Zadd myzset 1 one 在集合的位置1处添加一个值

      Zadd myzset 2 two 3 three 添加多个值

      Zrange myzset 0 -1 获取集合中的全部元素

      Zrem myzset one 移除集合中的元素

      Zcard myzset 获取有序集合中元素的个数                  

重要扩展和底层实现概念:

  • Bitmaps (位图): 这不是一个独立的数据类型,而是利用 String 类型的位操作命令 (SETBITGETBITBITCOUNTBITOP) 来实现的。它提供了一种极其节省空间的方式来存储和操作布尔值(0/1)信息(如用户每日签到)。

  • HyperLogLog (HLL): 用于高效估算海量数据集的基数(唯一元素个数)。它提供近似值(标准误差 <1%),但占用空间极小(固定约 12KB)。命令:PFADDPFCOUNTPFMERGE

  • Geospatial Indexes (地理空间索引): 基于 Sorted Set 实现,存储地理位置(经度、纬度)并提供附近位置搜索、计算距离等功能。命令:GEOADDGEOPOSGEODISTGEORADIUSGEORADIUSBYMEMBER

  • Streams (流): 在 Redis 5.0 引入,是一个更强大的、持久化的、支持多消费者的消息队列数据结构。它解决了 List 作为队列的一些限制(如消息持久化、消费状态跟踪、多消费者组)。命令:XADDXREADXREADGROUPXRANGEXACK 等。

  • 内部编码 (Internal Encoding): Redis 为了优化内存使用和性能,会根据存储的数据量、元素大小等因素,动态选择底层数据结构来表示同一个逻辑类型。例如:

    • Stringintembstrraw

    • Listziplist (小列表), linkedlist (旧), quicklist (Redis 3.2+ 默认)

    • Hashziplist (小哈希), hashtable

    • Setintset (整数小集合), hashtable

    • Sorted Setziplist (小有序集合), skiplist + dict (字典)

    • 使用 OBJECT ENCODING key 命令可以查看某个 Key 使用的内部编码。

选择数据结构的建议:

  1. 明确需求: 你需要存储什么?需要哪些操作(增删改查、范围查询、排序、集合运算)?性能要求如何?

  2. 利用特性: 每种结构都有其优势。用 Hash 存对象字段,用 Sorted Set 做排行榜,用 Set 去重和求交集,用 Bitmap 做布尔标记。

  3. 考虑内存和性能: 小数据集时内部编码(如 ziplist, intset)非常高效。超大 Key 会影响性能(如 SMEMBERS 大 Set)。

  4. 避免误用: 不要用不适合的结构(例如,试图用 List 实现复杂的消息队列功能,而应该用 Streams)。


网站公告

今日签到

点亮在社区的每一天
去签到