梳理学习Redis基本数据类型
Redis基本数据类型
redis有五种基本数据结构,分别为:String(字符串)、List(列表)、Hash(哈希)、Set(集合)、Zset(有序集合)
除此之外还有,bitmap、Hyperloglog、Geo、Stream等类型
在shell中,我们可以通过Help命令,查看对应数据结构的相关用法。返回的信息,包括,语法结构、作用描述、从哪一个版本的redis开始生效的
127.0.0.1:6379> help @list
BLMOVE source destination LEFT|RIGHT LEFT|RIGHT timeout
summary: Pops an element from a list, pushes it to another list and returns it. Blocks until an element is available otherwise. Deletes the list if the last element was moved.
since: 6.2.0
BLMPOP timeout numkeys key [key ...] LEFT|RIGHT [COUNT count]
summary: Pops the first element from one of multiple lists. Blocks until an element is available otherwise. Deletes the list if the last element was popped.
since: 7.0.0
BLPOP key [key ...] timeout
summary: Removes and returns the first element in a list. Blocks until an element is available otherwise. Deletes the list if the last element was popped.
since: 2.0.0
BRPOP key [key ...] timeout
summary: Removes and returns the last element in a list. Blocks until an element is available otherwise. Deletes the list if the last element was popped.
since: 2.0.0

1. String(字符串)
常用操作
| 操作命令 | 描述 |
|---|---|
| SET key value | 存入字符串键值对 |
| MSET key value [key value ...] | 批量存储字符串键值对 |
| SETNX key value | 存入一个不存在的字符串键值对(不存在则设置) |
| GET key | 获取一个字符串键值 |
| MGET key [key ...] | 批量获取字符串键值 |
| DEL key [key ...] | 删除一个或多个键 |
| EXPIRE key seconds | 设置一个键的过期时间(秒) |
| INCR key | 将 key 中储存的数字值加 1 |
| DECR key | 将 key 中储存的数字值减 1 |
| INCRBY key increment | 将 key 所储存的值加上 increment |
| DECRBY key decrement | 将 key 所储存的值减去 decrement |
应用场景
- 单值缓存:
SET key value - 对象缓存:两种方式
- 方式 1:
set user:1 '{"name":"roy","balance":1888}' - 方式 2:
MSET user:1:name roy user:1:balance 1888(更灵活)
- 方式 1:
- 分布式锁:
SETNX product:10001 true(获取锁)、DEL product:10001(释放锁),推荐SET product:10001 true ex 10 nx(防止死锁)
2. Hash(哈希)
常用操作
| 操作命令 | 描述 |
|---|---|
| HSET key field value | 存储一个哈希表 key 的键值 |
| HSETNX key field value | 存储一个不存在的哈希表 key 的键值(field 不存在则设置) |
| HMSET key field value [field value ...] | 在一个哈希表 key 中存储多个键值对 |
| HGET key field | 获取哈希表 key 对应的 field 键值 |
| HMGET key field [field ...] | 批量获取哈希表 key 中多个 field 键值 |
| HDEL key field [field ...] | 删除哈希表 key 中的 field 键值 |
| HLEN key | 返回哈希表 key 中 field 的数量 |
| HGETALL key | 返回哈希表 key 中所有的键值 |
| HINCRBY key field increment | 为哈希表 key 中 field 键的值加上增量 increment |
应用场景
- 对象缓存:
HSET user:1 name roy balance 1888(比 String 更易管理对象属性) - 电商购物车:
- 以用户 id 为 key(如
cart:1001) - 商品 id 为 field,商品数量为 value
- 操作:添加商品(
hset cart:1001 10088 1)、增减数量(hincrby)、删除商品(hdel)等
- 以用户 id 为 key(如
优缺点
- 优点:同类数据整合存储,便于管理;比 String 更省内存和 CPU
- 缺点:过期功能仅作用于 key,不支持 field 单独过期;Redis 集群下不适合大规模使用
3. List(列表)
常用操作
| 操作命令 | 描述 |
|---|---|
| LPUSH key value [value ...] | 将一个或多个值插入到 key 列表的表头(最左边) |
| RPUSH key value [value ...] | 将一个或多个值插入到 key 列表的表尾(最右边) |
| LPOP key | 移除并返回 key 列表的头元素 |
| RPOP key | 移除并返回 key 列表的尾元素 |
| LRANGE key start stop | 返回列表 key 中指定区间内的元素(start/stop 为偏移量) |
| BLPOP key [key ...] timeout | 从表头弹出元素,若为空则阻塞等待 timeout 秒(0 为永久) |
| BRPOP key [key ...] timeout | 从表尾弹出元素,若为空则阻塞等待 timeout 秒(0 为永久) |
应用场景
- 数据结构实现:
- 栈:
LPUSH + LPOP - 队列:
LPUSH + RPOP - 阻塞队列:
LPUSH + BRPOP
- 栈:
- 实际场景:视频列表、签到列表、排队机、简化版消息队列(MQ)
注意点
- 容量上限:2^32-1 个元素(约 40 亿),但需避免大 key 问题
- 底层为双向链表:双端操作性能高,中间节点索引操作性能低
4. Set(集合)
常用操作
| 操作命令 | 描述 |
|---|---|
| SADD key member [member ...] | 往集合 key 中存入元素(元素存在则忽略,key 不存在则新建) |
| SREM key member [member ...] | 从集合 key 中删除元素 |
| SMEMBERS key | 获取集合 key 中所有元素 |
| SCARD key | 获取集合 key 的元素个数 |
| SISMEMBER key member | 判断 member 是否存在于集合 key 中 |
| SRANDMEMBER key [count] | 从集合 key 中选出 count 个元素(不删除) |
| SPOP key [count] | 从集合 key 中选出 count 个元素(删除) |
| SINTER key [key ...] | 计算多个集合的交集 |
| SINTERSTORE destination key [key ...] | 将交集结果存入新集合 destination |
| SUNION key [key ...] | 计算多个集合的并集 |
| SUNIONSTORE destination key [key ...] | 将并集结果存入新集合 destination |
| SDIFF key [key ...] | 计算多个集合的差集 |
| SDIFFSTORE destination key [key ...] | 将差集结果存入新集合 destination |
应用场景
- 微信抽奖小程序:
- 参与抽奖:
SADD key {userID} - 查看参与者:
SMEMBERS key - 抽奖:
SRANDMEMBER key [count](不删除)或SPOP key [count](删除)
- 参与抽奖:
- 点赞 / 收藏 / 标签:
- 点赞:
SADD like:{消息ID} {用户ID} - 取消点赞:
SREM like:{消息ID} {用户ID} - 检查是否点赞:
SISMEMBER like:{消息ID} {用户ID}
- 点赞:
- 社交关系:
- 共同关注:
SINTER set1 set2 - 推荐好友:
SDIFF set1 set2
- 共同关注:
5. Sorted Set(ZSet,有序集合)
常用操作
| 操作命令 | 描述 |
|---|---|
| ZADD key score member [[score member]...] | 往有序集合 key 中加入带分值元素 |
| ZREM key member [member ...] | 从有序集合 key 中删除元素 |
| ZSCORE key member | 返回有序集合 key 中元素 member 的分值 |
| ZINCRBY key increment member | 为有序集合 key 中元素 member 的分值加 increment |
| ZCARD key | 返回有序集合 key 中元素个数 |
| ZRANGE key start stop [WITHSCORES] | 正序获取有序集合 key 从 start 到 stop 下标的元素(带分值可选) |
| ZREVRANGE key start stop [WITHSCORES] | 倒序获取有序集合 key 从 start 到 stop 下标的元素(带分值可选) |
| ZUNIONSTORE destkey numkeys key [key ...] | 计算多个有序集合的并集并存入 destkey |
| ZINTERSTORE destkey numkeys key [key ...] | 计算多个有序集合的交集并存入 destkey |
应用场景
- 排行榜:
- 点击新闻计数:
ZINCRBY hotNews:20190819 1 守护香港 - 当日排行前十:
ZREVRANGE hotNews:20190819 0 9 WITHSCORES - 七日榜单:
ZUNIONSTORE合并 7 天数据后查询
- 点击新闻计数:
6. Bitmap(位图)
常用操作
| 操作命令 | 描述 | |
|---|---|---|
| SETBIT key offset value | 将二进制数组的 offset 位置设置为 value(0 或 1) | |
| GETBIT key offset | 返回二进制数组 offset 位置的值 | |
| BITCOUNT key [start end [BYTE | BIT]] | 返回二进制数组中 1 的个数 |
| BITPOS key bit [start [end [BYTE | BIT]]] | 返回 bitmap 中第一个值为 bit 的 offset 位置 |
| BITOP AND|OR|XOR|NOT destkey key [key ...] | 对多个 bitmap 做二进制的与 / 或 / 异或 / 非运算 |
应用场景
- 每日签到:
- 签到记录:
SETBIT dailycheck:1 100 1(1 号用户第 100 天签到) - 签到次数:
BITCOUNT dailycheck:1 - 首次签到时间:
BITPOS dailycheck:1 1
- 签到记录:
优点
- 快速、高效、节省空间(用 bit 存储,1 字节可存 8 天签到状态)
7. HyperLogLog
作用
用于统计集合中不重复元素的个数(基数统计),适合大数据量场景(如 UV 统计)。
功能很简单,底层的算法不简单。他的效率非常高,适合大数据量场景下的统计
常用操作
| 操作命令 | 描述 |
|---|---|
| PFADD key element [element ...] | 添加元素到 HyperLogLog |
| PFCOUNT key | 统计 key 中不重复元素的个数 |
| PFMERGE destkey [sourcekey ...] | 合并多个 HyperLogLog 数据到 destkey |
应用场景
- 网站 UV 统计:
PFADD visitlog 用户IP记录访问,PFCOUNT visitlog统计独立访客
8. Geo(地理空间)
常用操作
| 操作命令 | 描述 |
|---|---|
| GEOADD key [NX|XX] [CH] longitude latitude member ... | 添加一个或多个地点(经纬度 + 名称) |
| GEOPOS key [member ...] | 返回指定地点的经纬度 |
| GEODIST key member1 member2 [M|KM|FT|MI] | 计算两个地点的距离(单位可选:米 / 千米 / 英尺 / 英里) |
| GEORADIUS key longitude latitude radius 单位 [选项] | 查询指定经纬度附近的地点(带距离、坐标等可选) |
| GEOSEARCH key FROMMEMBER|FROMLONLAT ... | 查询指定地点 / 经纬度附近的地点(支持半径 / 矩形范围) |
应用场景
- 地理位置相关功能:
- 添加商家地址:
GEOADD changsha 113.017489 28.200454 火车站 ... - 查找附近景点:
GEORADIUS changsha 113.017489 28.200454 2 KM
- 添加商家地址:
9. Stream(流)
作用
类似 “阻塞队列 + 发布订阅” 的结合体,可作为 Redis 版消息队列(企业应用较少)。
常用操作
| 操作命令 | 描述 |
|---|---|
| XADD key [选项] *|id field value ... | 往队列末尾发布消息(* 表示自动生成 ID) |
| XDEL key id [id ...] | 删除队列中的消息 |
| XLEN key | 获取队列长度 |
| XRANGE key start end [COUNT count] | 查询队列中的消息(- 表示开始,+ 表示结尾) |
| XGROUP CREATE key groupname 0|$ | 创建消费者组(0 从头部消费,$ 从尾部消费) |
| XREADGROUP GROUP groupname consumername COUNT n STREAMS key > | 消费者组内消费消息(> 表示未消费消息) |
应用场景
- 简化版消息队列(MQ)
在SpringBoot中使用Redis
引入依赖包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
那些连接mysql、es等其他数据库的包,也都是spring-boot-starter-data集合下的
添加配置类
没有配置类,redis也能使用,项目启动后springboot会通过IOC注入一个默认的RedisTemplate实例,但是默认的RedisTemplate存在中文乱码问题
@Configuration
@ConditionalOnClass(RedisTemplate.class)
public class RedisConfig {
@Bean
public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
// GenericJackson2JsonRedisSerializer jsonSerializer = new GenericJackson2JsonRedisSerializer();
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
GenericToStringSerializer<String> genericToStringSerializer = new GenericToStringSerializer<>(String.class);
//指定key和value的序列化方式
redisTemplate.setKeySerializer(stringRedisSerializer);
redisTemplate.setValueSerializer(genericToStringSerializer);
redisTemplate.setHashKeySerializer(stringRedisSerializer);
redisTemplate.setHashValueSerializer(stringRedisSerializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}
调用RedisTemplate接口
@Resource
private StringRedisTemplate stringRedisTemplate;
@Test
public void test()
{
stringRedisTemplate.opsForValue().set("test3","楼兰");
System.out.println(stringRedisTemplate.opsForValue().get("test3"));
System.out.println(stringRedisTemplate.opsForValue().get("test2"));
}

浙公网安备 33010602011771号