Redis数据类型及操作命令
概述
5种基础数据类型:String、List、Set、Zset、Hash
3种特殊数据类型:
- geospatial(地理空间的),底层是Zset
- hyperloglog:(基数==不重复的元素)
- bitmaps:(位存储)
Stream 类型:
Redis5.0 中还增加了一个数据结构Stream,它借鉴了Kafka的设计,是一个新的强大的支持多播的可持久化的消息队列。
详述
String (字符串)
描述: 最基本的数据类型。一个 Key 对应一个 Value。Value 不仅是文本字符串,也可以是数字(整数或浮点数)或二进制数据(如图片、序列化对象)。
特点:
最大容量:512 MB。
可以对数字执行原子操作:
INCR
,DECR
,INCRBY
,DECRFLOAT
等。支持部分字符串操作:
APPEND
,GETRANGE
,SETRANGE
,STRLEN
。支持位操作:
SETBIT
,GETBIT
,BITCOUNT
,BITOP
(位图功能)。
常见用途:
缓存 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命令将覆写旧值。
List (列表)
描述: 一个有序的字符串集合,按照插入顺序排序。你可以从列表的两端添加或移除元素。
特点:
双向链表实现(底层是 quicklist)。
支持在头部(Left)和尾部(Right)高效插入/删除:
LPUSH
,RPUSH
,LPOP
,RPOP
。支持范围查询:
LRANGE
。支持阻塞操作:
BLPOP
,BRPOP
(用于简单的消息队列)。可以修剪列表:
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。
Hash (哈希表 / 字典)
描述: 一个键值对集合,特别适合存储对象(如用户信息、产品信息)。
特点:
一个 Key 对应一个 field-value 映射表。
可以高效地操作单个字段:
HSET
,HGET
,HDEL
,HEXISTS
。支持批量操作:
HMSET
,HMGET
,HGETALL
。支持对数值字段进行原子增减:
HINCRBY
,HINCRBYFLOAT
。可以获取所有字段名或字段值:
HKEYS
,HVALS
。最大字段数: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
Set (集合)
描述: 一个无序的、唯一的字符串集合。集合成员不允许重复。
特点:
高效的添加、删除、检查成员是否存在:
SADD
,SREM
,SISMEMBER
。支持集合运算:
SINTER
(交集),SUNION
(并集),SDIFF
(差集)。支持获取所有成员:
SMEMBERS
(谨慎使用,大数据量可能阻塞)。支持随机获取成员:
SRANDMEMBER
,SPOP
。支持获取集合大小:
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的并集
Sorted Set (有序集合 / ZSet)
描述: 类似于 Set,但每个成员都关联一个分数 (
score
),成员按分数排序(默认升序)。分数可以重复,但成员唯一。特点:
通过分数进行范围查询:
ZRANGEBYSCORE
,ZREVRANGEBYSCORE
。通过排名(位置)进行查询:
ZRANGE
,ZREVRANGE
(支持WITHSCORES
)。高效添加、删除、更新分数:
ZADD
(可更新分数),ZREM
。支持获取成员排名:
ZRANK
,ZREVRANK
。支持获取成员分数:
ZSCORE
。支持集合运算(按分数聚合):
ZUNIONSTORE
,ZINTERSTORE
。支持获取集合大小:
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 类型的位操作命令 (
SETBIT
,GETBIT
,BITCOUNT
,BITOP
) 来实现的。它提供了一种极其节省空间的方式来存储和操作布尔值(0/1)信息(如用户每日签到)。HyperLogLog (HLL): 用于高效估算海量数据集的基数(唯一元素个数)。它提供近似值(标准误差 <1%),但占用空间极小(固定约 12KB)。命令:
PFADD
,PFCOUNT
,PFMERGE
。Geospatial Indexes (地理空间索引): 基于 Sorted Set 实现,存储地理位置(经度、纬度)并提供附近位置搜索、计算距离等功能。命令:
GEOADD
,GEOPOS
,GEODIST
,GEORADIUS
,GEORADIUSBYMEMBER
。Streams (流): 在 Redis 5.0 引入,是一个更强大的、持久化的、支持多消费者的消息队列数据结构。它解决了 List 作为队列的一些限制(如消息持久化、消费状态跟踪、多消费者组)。命令:
XADD
,XREAD
,XREADGROUP
,XRANGE
,XACK
等。内部编码 (Internal Encoding): Redis 为了优化内存使用和性能,会根据存储的数据量、元素大小等因素,动态选择底层数据结构来表示同一个逻辑类型。例如:
String
:int
,embstr
,raw
List
:ziplist
(小列表),linkedlist
(旧),quicklist
(Redis 3.2+ 默认)Hash
:ziplist
(小哈希),hashtable
Set
:intset
(整数小集合),hashtable
Sorted Set
:ziplist
(小有序集合),skiplist
+dict
(字典)使用
OBJECT ENCODING key
命令可以查看某个 Key 使用的内部编码。
选择数据结构的建议:
明确需求: 你需要存储什么?需要哪些操作(增删改查、范围查询、排序、集合运算)?性能要求如何?
利用特性: 每种结构都有其优势。用 Hash 存对象字段,用 Sorted Set 做排行榜,用 Set 去重和求交集,用 Bitmap 做布尔标记。
考虑内存和性能: 小数据集时内部编码(如 ziplist, intset)非常高效。超大 Key 会影响性能(如
SMEMBERS
大 Set)。避免误用: 不要用不适合的结构(例如,试图用 List 实现复杂的消息队列功能,而应该用 Streams)。