Redis的数据类型和底层数据结构

Redis的数据类型和底层数据结构

Redis的数据类型

string字符串类

Redis的String能表达3种值的类型:字符串、整数、浮点数

常见操作命令如下表:

命令名称命令格式命令描述
set set key value 赋值
get get key 取值
getset getset key value 取值并赋值
setnx setnx key value 当value不存在时采用赋值set key value NX PX 3000 原子操作,px 设置毫秒数
append append key value 向尾部追加值
strlen strlen key 获取字符串长度
incr incr key 递增数字
incrby incrby key increment 增加指定的整数
decr decr key 递减数字
decrby decrby key decrement 减少指定的整数

应用场景: 1、key和命令是字符串 2、普通的赋值 3、incr用于乐观锁 incr:递增数字,可用于实现乐观锁 watch(事务) 4、setnx用于分布式锁 当value不存在时采用赋值,可用于实现分布式锁

list列表类型

list列表类型可以存储有序、可重复的元素 获取头部或尾部附近的记录是极快的 list的元素个数最多为2^32-1个(40亿) 常见操作命令如下表:

命令名称命令格式描述
lpush lpush key v1 v2 v3 ... 从左侧插入列表
lpop lpop key 从列表左侧取出
rpush rpush key v1 v2 v3 ... 从右侧插入列表
rpop rpop key 从列表右侧取出
lpushx lpushx key value 将值插入到列表头部
rpushx rpushx key value 将值插入到列表尾部
blpop blpop key timeout 从列表左侧取出,当列表为空时阻塞,可以设置最大阻塞时 间,单位为秒
brpop blpop key timeout 从列表右侧取出,当列表为空时阻塞,可以设置最大阻塞时 间,单位为秒
llen llen key 获得列表中元素个数
lindex lindex key index 获得列表中下标为index的元素 index从0开始
lrange lrange key start end 返回列表中指定区间的元素,区间通过start和end指定
lrem lrem key count value 删除列表中与value相等的元素 当count>0时, lrem会从列表左边开始删除;当count<0时, lrem会从列表后边开始删除;当count=0时, lrem删除所有 值为value的元素
lset lset key index value 将列表index位置的元素设置成value的值
ltrim ltrim key start end 对列表进行修剪,只保留start到end区间
rpoplpush rpoplpush key1 key2 从key1列表右侧弹出并插入到key2列表左侧
brpoplpush brpoplpush key1 key2 从key1列表右侧弹出并插入到key2列表左侧,会阻塞
linsert linsert key BEFORE/AFTER pivot value 将value插入到列表,且位于值pivot之前或之后

应用场景: 1、作为栈或队列使用 列表有序可以作为栈和队列使用 2、可用于各种列表,比如用户列表、商品列表、评论列表等。

set集合类型

Set:无序、唯一元素 集合中最大的成员数为 2^32 - 1 常见操作命令如下表:

命令名称命令格式描述
sadd sadd key mem1 mem2 .... 为集合添加新成员
srem srem key mem1 mem2 .... 删除集合中指定成员
smembers smembers key 获得集合中所有元素
spop spop key 返回集合中一个随机元素,并将该元素删除
srandmember srandmember key 返回集合中一个随机元素,不会删除该元素
scard scard key 获得集合中元素的数量
sismember sismember key member 判断元素是否在集合内
sinter sinter key1 key2 key3 求多集合的交集
sdiff sdiff key1 key2 key3 求多集合的差集
sunion sunion key1 key2 key3 求多集合的并集

应用场景: 适用于不能重复的且不需要顺序的数据结构 比如:关注的用户,还可以通过spop进行随机抽奖

sortedset有序集合类型

SortedSet(ZSet) 有序集合: 元素本身是无序不重复的 每个元素关联一个分数(score) 可按分数排序,分数可重复 常见操作命令如下表:

命令名称命令格式描述
zadd zadd key score1 member1 score2 member2 ... 为有序集合添加新成员
zrem zrem key mem1 mem2 .... 删除有序集合中指定成员
zcard zcard key 获得有序集合中的元素数量
zcount zcount key min max 返回集合中score值在[min,max]区间 的元素数量
zincrby zincrby key increment member 在集合的member分值上加increment
zscore zscore key member 获得集合中member的分值
zrank zrank key member 获得集合中member的排名(按分值从 小到大)
zrevrank zrevrank key member 获得集合中member的排名(按分值从 大到小)
zrange zrange key start end 获得集合中指定区间成员,按分数递增 排序
zrevrange zrevrange key start end 获得集合中指定区间成员,按分数递减 排序

应用场景: 由于可以按照分值排序,所以适用于各种排行榜。比如:点击排行榜、销量排行榜、关注排行榜等。

hash类型(散列表)

Redis hash 是一个 string 类型的 field 和 value 的映射表,它提供了字段和字段值的映射。 每个 hash 可以存储 2^32 - 1 键值对(40多亿)。

image-20210609221410744

常见操作命令如下表:

命令名称命令格式描述
hset hset key field value 赋值,不区别新增或修改
hmset hmset key field1 value1 field2 value2 批量赋值
hsetnx hsetnx key field value 赋值,如果filed存在则不操作
hexists hexists key filed 查看某个field是否存在
hget hget key field 获取一个字段值
hmget hmget key field1 field2 ... 获取多个字段值
hgetall hgetall key  
hdel hdel key field1 field2... 删除指定字段
hincrby hincrby key field increment 指定字段自增increment
hlen hlen key 获得字段数量

应用场景: 对象的存储 ,表数据的映射

bitmap位图类型

bitmap是进行位操作的 通过一个bit位来表示某个元素对应的值或者状态,其中的key就是对应元素本身。 bitmap本身会极大的节省储存空间。 常见操作命令如下表:

命令名称命令格式描述
setbit setbit key offset value 设置key在offset处的bit值(只能是0或者 1)。
getbit getbit key offset 获得key在offset处的bit值
bitcount bitcount key 获得key的bit位为1的个数
bitpos bitpos key value 返回第一个被设置为bit值的索引值
bitop bitop and[or/xor/not] destkey key [key …] 对多个key 进行逻辑运算后存入destkey 中

应用场景: 1、用户每月签到,用户id为key , 日期作为偏移量 1表示签到

2、统计活跃用户, 日期为key,用户id为偏移量 1表示活跃

3、查询用户在线状态, 日期为key,用户id为偏移量 1表示在线

geo地理位置类型

geo是Redis用来处理位置信息的。在Redis3.2中正式使用。主要是利用了Z阶曲线、Base32编码和 geohash算法

常见操作命令如下表:

命令名称命令格式描述
geoadd geoadd key 经度 纬度 成员名称1 经度1 纬度1 成 员名称2 经度2 纬度 2 ... 添加地理坐标
geohash geohash key 成员名称1 成员名称2... 返回标准的 geohash串
geopos geopos key 成员名称1 成员名称2... 返回成员经纬度
geodist geodist key 成员1 成员2 单位 计算成员间距离
georadiusbymember georadiusbymember key 成员 值单位 count 数 asc[desc] 根据成员查找附近的成员

应用场景: 1、记录地理位置 2、计算距离 3、查找"附近的人"

stream数据流类型

stream是Redis5.0后新增的数据结构,用于可持久化的消息队列。 几乎满足了消息队列具备的全部内容,包括:

  • 消息ID的序列化生成

  • 消息遍历

  • 消息的阻塞和非阻塞读取

  • 消息的分组消费

  • 未完成消息的处理

  • 消息队列监控

每个Stream都有唯一的名称,它就是Redis的key,首次使用 xadd 指令追加消息时自动创建。 常见操作命令如下表:

命令名称命令格式描述
xadd xadd key id <*> field1 value1.... 将指定消息数据追加到指定队列(key)中,表示最新生成的id(当前时间+序列号)
xread xread [COUNT count] [BLOCK milliseconds] STREAMS key [key ...] ID [ID ...] 从消息队列中读取,COUNT:读取条数, BLOCK:阻塞读(默认不阻塞)key:队列 名称 id:消息id
xrange xrange key start end [COUNT] 读取队列中给定ID范围的消息 COUNT:返 回消息条数(消息id从小到大)
xrevrange xrevrange key start end [COUNT] 读取队列中给定ID范围的消息 COUNT:返 回消息条数(消息id从大到小)
xdel xdel key id 删除队列的消息
xgroup xgroup create key groupname id 创建一个新的消费组
xgroup xgroup destory key groupname 删除指定消费组
xgroup xgroup delconsumer key groupname cname 删除指定消费组中的某个消费者
xgroup xgroup setid key id 修改指定消息的最大id
xreadgroup xreadgroup group groupname consumer COUNT streams key 从队列中的消费组中创建消费者并消费数据 (consumer不存在则创建)

应用场景:

消息队列的使用

底层数据结构

redis的所有数据类型底层存储都是以一种统一的格式(RedisObject结构)进行存储。

结构信息:

typedef struct redisObject {    
   unsigned type:4;//类型 五种对象类型    
   unsigned encoding:4;//编码    
   void *ptr;//指向底层实现数据结构的指针    
   //...    
   int refcount;//引用计数    
   //...    
   unsigned lru:LRU_BITS; //LRU_BITS为24bit 记录最后一次被命令程序访问的时间    
   //...
}robj;

4位type

type 字段表示对象的类型,占 4 位; REDIS_STRING(字符串)、REDIS_LIST (列表)、REDIS_HASH(哈希)、REDIS_SET(集合)、REDIS_ZSET(有 序集合)。 当我们执行 type 命令时,便是通过读取 RedisObject 的 type 字段获得对象的类型。

4位encoding

encoding 表示对象的内部编码,占 4 位 每个对象有不同的实现编码 Redis 可以根据不同的使用场景来为对象设置不同的编码,大大提高了 Redis 的灵活性和效率。 通过 object encoding 命令,可以查看对象采用的编码方式

24位LRU

lru 记录的是对象最后一次被命令程序访问的时间,( 4.0 版本占 24 位,2.6 版本占 22 位)。 高16位存储一个分钟数级别的时间戳,低8位存储访问计数(lfu : 最近访问次数) lru----> 高16位: 最后被访问的时间 lfu----->低8位:最近访问次数

refcount

refcount 记录的是该对象被引用的次数,类型为整型。 refcount 的作用,主要在于对象的引用计数和内存回收。 当对象的refcount>1时,称为共享对象 Redis 为了节省内存,当有一些对象重复出现时,新的程序不会创建新的对象,而是仍然使用原来的对 象。

ptr

ptr 指针指向具体的数据,比如:set hello world,ptr 指向包含字符串 world 的 SDS

 

 

posted @ 2021-06-09 23:32  alwaysFly  阅读(175)  评论(0编辑  收藏  举报