Redis 数据类型
在Redis中,数据类型是构建其强大功能的核心。Redis支持多种数据类型,每种类型都为不同的使用场景提供了高效的数据存储和操作方式。理解这些数据类型的意义对于有效利用Redis至关重要。
Redis 主要支持以下几种数据类型:
string(字符串): 基本的数据存储单元,可以存储字符串、整数或者浮点数。
hash(哈希):一个键值对集合,可以存储多个字段。
list(列表):一个简单的列表,可以存储一系列的字符串元素。
set(集合):一个无序集合,可以存储不重复的字符串元素。
zset(sorted set:有序集合) : 类似于集合,但是每个元素都有一个分数(score)与之关联。
位图(Bitmaps):基于字符串类型,可以对每个位进行操作。
超日志(HyperLogLogs):用于基数统计,可以估算集合中的唯一元素数量。
地理空间(Geospatial):用于存储地理位置信息。
发布/订阅(Pub/Sub):一种消息通信模式,允许客户端订阅消息通道,并接收发布到该通道的消息。
流(Streams):用于消息队列和日志存储,支持消息的持久化和时间排序。
String(字符串)
string 是 redis 最基本的类型,可以理解成与 Memcached 一模一样的类型,一个 key 对应一个 value。
string 类型是二进制安全的。意思是 redis 的 string 可以包含任何数据,比如jpg图片或者序列化的对象。
string 类型是 Redis 最基本的数据类型,string 类型的值最大能存储 512MB。
常用命令
SET key value:设置键的值
GET key: 获取键的值
INCR key: 将键的值加 1
DECR key: 将键的值减 1
APPEND key value:将值追加到键的值之后#注意:一个键最大能存储 512MB !!!
Hash(哈希)
Redis hash 是一个键值(key=>value)对集合
hash 特别适合用于存储对象。
每个哈希最多可以存储 2^32 - 1 个键值对。
常用命令
HSET key field value:设置哈希表中字段的值
HGET key field: 获取哈希表中字段的值
HGETALL key: 获取哈希表中所有字段和值
HDEL key field:删除哈希表中的一个或多个字段List(列表)
Redis 列表是简单的字符串列表,按照插入顺序排序。可以添加一个元素到列表的头部(左边)或者尾部(右边)。
列表最多可以存储 232 - 1 个元素。
常用命令
LPUSH key value:将值插入到列表头部
RPUSH key value:将值插入到列表尾部
LPOP key: 移出并获取列表的第一个元素
RPOP key: 移出并获取列表的最后一个元素
LRANGE key start stop:获取列表在指定范围内的元素Set(集合)
Redis 的 Set 是 string 类型的无序集合。
集合是通过哈希表实现的,添加,删除,查找的复杂度都是 O(1)。
时间复杂度O(1)表示一个算法的执行时间(或执行步骤数)是常数,也就是说,无论输入数据的规模如何变化,算法的执行时间始终保持不变
常用命令
SADD key value: 向集合添加一个或多个成员
SREM key value: 移除集合中的一个或多个成员
SMEMBERS key: 返回集合中的所有成员
SISMEMBER key value:判断值是否是集合的成员添加一个 string 元素到 key 对应的 set 集合中,成功返回 1,如果元素已经在集合中返回 0。
根据集合内元素的唯一性,第二次插入重复的元素将被忽略
集合中最大的成员数为 232 - 1(4294967295, 每个集合可存储40多亿个成员)。
zset(sorted set:有序集合)
Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。
zset的成员是唯一的,但分数(score)却可以重复。
常用命令
ZADD key score value: 向有序集合添加一个或多个成员,或更新已存在成员的分数。
ZRANGE key start stop [WITHSCORES]: 返回指定范围内的成员。
ZREM key value: 移除有序集合中的一个或多个成员。
ZSCORE key value: 返回有序集合中,成员的分数值。添加元素到集合,元素在集合中存在则更新对应score。
位图(Bitmaps)
Bitmaps在Redis中并不是一种独立的数据结构,而是基于字符串类型的位操作。每个位只能是0或1,可以用来表示某种状态,比如用户是否在线,或者某个功能是否被开启。这样的话,Bitmaps可以非常节省空间,特别是当需要存储大量的布尔值时。
位图结构:基于字符串,每个位存储0或1,偏移量(offset)从0开始。
适用场景:用户行为追踪(登录、签到)、实时统计、布隆过滤器等。
内存效率:每个用户仅占1位,百万用户仅需约122KB。
SETBIT user:login:20231001 1000 1 # 用户ID 1000 在2023-10-01登录
GETBIT user:login:20231001 1000 # 返回1表示已登录
BITCOUNT user:login:20231001 # 统计当天总登录用户数# 统计每周连续登录用户
# 每天记录用户登录状态
SETBIT user:login:day1 1000 1
SETBIT user:login:day2 1000 1
...
SETBIT user:login:day7 1000 1
# 计算7天的交集(AND操作)
BITOP AND weekly_active user:login:day1 ... user:login:day7
# 统计连续登录用户数
BITCOUNT weekly_active超日志(HyperLogLogs)
用于基数估计算法的数据结构, 常用于统计唯一值的近似值。
什么是基数?
比如数据集 {1, 3, 5, 7, 5, 7, 8}, 那么这个数据集的基数集为 {1, 3, 5 ,7, 8}, 基数(不重复元素)为5。 基数估计就是在误差可接受的范围内,快速计算基数。
redis 127.0.0.1:6379> PFADD runoobkey "redis" #添加指定元素到 HyperLogLog 中
1) (integer) 1
redis 127.0.0.1:6379> PFADD runoobkey "mongodb" #添加指定元素到 HyperLogLog 中
1) (integer) 1
redis 127.0.0.1:6379> PFADD runoobkey "mysql" #添加指定元素到 HyperLogLog 中
1) (integer) 1
redis 127.0.0.1:6379> PFCOUNT runoobkey #返回给定 HyperLogLog 的基数估算值
(integer) 3
地理空间(Geospatial)
主要用于存储地理位置信息,并对存储的信息进行操作,支持地理空间索引和半径查询
# GEO 操作方法有:
geoadd: 添加地理位置的坐标。
geopos: 获取地理位置的坐标。
geodist:计算两个位置之间的距离。
georadius: 根据用户给定的经纬度坐标来获取指定范围内的地理位置集合。
georadiusbymember:根据储存在位置集合里面的某个地点获取指定范围内的地理位置集合。
geohash: 返回一个或多个位置对象的 geohash 值。发布订阅 (pub/sub)
发布订阅 (pub/sub) 是一种消息通信模式:发送者 (pub) 发送消息,订阅者 (sub) 接收消息。
#创建了订阅频道名为 runoobChat:
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "runoobChat"
3) (integer) 1# 在同一个频道 runoobChat 发布两次消息,订阅者就能接收到消息
redis 127.0.0.1:6379> PUBLISH runoobChat "Redis PUBLISH test"
(integer) 1
redis 127.0.0.1:6379> PUBLISH runoobChat "Learn redis by runoob.com"
(integer) 1流(Streams)
Redis Stream 是 Redis 5.0 版本新增加的数据结构,主要用于消息队列(MQ,Message Queue)
Redis 本身是有一个发布订阅 (pub/sub) 来实现消息队列的功能,但它有个缺点就是消息无法持久化,如果出现网络断开、Redis 宕机等,消息就会被丢弃。简单来说发布订阅 (pub/sub) 可以分发消息,但无法记录历史消息。
Stream 流数据类型是专门为消息队列设计的,提供了比列表更丰富的功能,如消息持久化、消费者组管理等。流允许你按时间顺序存储消息,并支持消费者组,这使得多个消费者可以独立地消费同一流中的消息。
使用场景选择
简单队列:如果你只需要一个简单的队列,并且不需要复杂的消息管理功能,使用列表可能就足够了。
高级队列:如果你需要更高级的功能,如持久化、消费者组管理等,使用流会是更好的选择。
实时消息传递:对于需要实时消息传递的应用,发布/订阅系统是一个很好的选择。
注意事项
持久性:默认情况下,Redis 使用内存存储数据。对于需要持久化的场景,可以考虑配置 Redis 的 AOF(Append Only File)或 RDB(Redis Database)持久化。
性能和扩展性:虽然 Redis 非常快速和可扩展,但在高负载情况下仍需注意其性能和内存使用情况。对于非常大的消息队列,可能需要考虑分片或使用其他更专业的消息队列系统如 RabbitMQ 或 Kafka。