redis数据,编码和数据结构关系

Redis的类型系统包括redisObject对象,用于类型检查和多态。5种数据类型(string、list、set、zset、hash)有多种编码,如int、raw、embstr、ziplist、linkedlist等,编码转换根据对象特性和操作自动进行。内存回收通过refcount属性实现,内存共享节省内存成本。常用命令如set、get、lpush、rpop、sadd、zrangebyscore等,适用于计数、消息队列、去重、排行榜等场景。
摘要由CSDN通过智能技术生成

Redis构建的类型系统

Redis构建了自己的类型系统,主要包括

  • redisObject对象
  • 基于redisObject对象的类型检查
  • 基于redisObject对象的显示多态函数
  • 对redisObject进行分配、共享和销毁的机制

C语言不是面向对象语言,这里将redisObject称呼为对象是为了讲述方便,让里面的内容更容易被理解,redisObject其实是一个结构体。

redisObject对象

Redis内部使用一个redisObject对象来表示所有的key和value,每次在Redis数据块中创建一个键值对时,一个是键对象,一个是值对象,而Redis中的每个对象都是由redisObject结构来表示。

在Redis中,键总是一个字符串对象,而值可以是字符串、列表、集合等对象,所以我们通常说键为字符串键,表示这个键对应的值为字符串对象,我们说一个键为集合键时,表示这个键对应的值为集合对象

redisobject最主要的信息:

redisobject源码
typedef struct redisObject{
     //类型
     unsigned type:4;
     //编码
     unsigned encoding:4;
     //指向底层数据结构的指针
     void *ptr;
     //引用计数
     int refcount;
     //记录最后一次被程序访问的时间
     unsigned lru:22;
}robj
  • type代表一个value对象具体是何种数据类型

    • type key :判断对象的数据类型
  • encoding属性和*prt指针

    • prt指针指向对象底层的数据结构,而数据结构由encoding属性来决定

      数据结构和编码的对应

    • 每种类型的对象至少使用了两种不同的编码,而这些编码对用户是完全透明的。

      数据类型和编码的对应

    • object encoding key命令可以查看值对象的编码

命令的类型检查和多态

Redis命令分类
  • 一种是只能用于对应数据类型的命令,例如LPUSH和LLEN只能用于列表键, SADD 和 SRANDMEMBER只能用于集合键。
  • 另一种是可以用于任何类型键的命令。比如TTL。

当执行一个处理数据类型的命令时,Redis执行以下步骤:

  • 根据给定 key ,在数据库字典中查找和它相对应的 redisObject ,如果没找到,就返回 NULL
  • 检查 redisObjecttype 属性和执行命令所需的类型是否相符,如果不相符,返回类型错误。
  • 根据 redisObjectencoding 属性所指定的编码,选择合适的操作函数来处理底层的数据结构。
  • 返回数据结构的操作结果作为命令的返回值。

5种数据类型对应的编码和数据结构

string

string 是最常用的一种数据类型,普通的key/value存储都可以归结为string类型,value不仅是string,也可以是数字。其他几种数据类型的构成元素也都是字符串,注意Redis规定字符串的长度不能超过512M

  • 编码
    字符串对象的编码可以是int raw embstr
    • int编码
      • 保存的是可以用long类型表示的整数值
    • raw编码
      • 保存长度大于44字节的字符串
    • embstr编码
      • 保存长度小于44字节的字符串

int用来保存整数值,raw用来保存长字符串,embstr用来保存短字符串。embstr编码是用来专门保存短字符串的一种优化编码。

Redis中对于浮点型也是作为字符串保存的,在需要时再将其转换成浮点数类型

  • 编码的转换

    • 当 int 编码保存的值不再是整数,或大小超过了long的范围时,自动转化为raw
    • 对于 embstr 编码,由于 Redis 没有对其编写任何的修改程序(embstr 是只读的),在对embstr对象进行修改时,都会先转化为raw再进行修改,因此,只要是修改embstr对象,修改后的对象一定是raw的,无论是否达到了44个字节。
  • 常用命令

    • set/get

      • set:设置key对应的值为string类型的value (多次set name会覆盖)
      • get:获取key对应的值
    • mset /mget

      • mset 批量设置多个key的值,如果成功表示所有值都被设置,否则返回0表示没有任何值被设置
      • mget批量获取多个key的值,如果不存在则返回null
      127.0.0.1:6379> mset user1:name redis user1:age 22
      OK
      127.0.0.1:6379>  mget user1:name user1:age
      1) "redis"
      2) "22"
      
      • 应用场景
        • 类似于哈希操作,存储对象
    • incr && incrby<原子操作>

      • incr对key对应的值进行加加操作,并返回新的值,incrby加指定的值
    • decr && decrby<原子操作>

      • decr对key对应的值进行减减操做,并返回新的值,decrby减指定的值
    • setnx <小小体验一把分布式锁,真香>

      • 设置Key对应的值为string类型的值,如果已经存在则返回0
    • setex

      • 设置key对应的值为string类型的value,并设定有效期
    • setrange/getrange

      • setrange从指定位置替换字符串
      • getrange获取key对应value子字符串
  • 其他命令

    • msetnx 同mset,不存在就设置,不会覆盖已有的key
    • getset 设置key的值,并返回key旧的值
    • append 给指定的key的value追加字符串,并返回新字符串的长度
    • strlen 返回key对应的value字符串的长度
  • 应用场景

    • 因为string类型是二进制安全的,可以用来存放图片,视频等内容。
    • 由于redis的高性能的读写功能,而string类型的value也可以是数字,可以用做计数器(使用INCR,DECR指令)。比如分布式环境中统计系统的在线人数,秒杀等。
    • 除了上面提到的,还有用于SpringSession实现分布式session
    • 分布式系统全局序列号

list

list列表,它是简单的字符串列表,你可以添加一个元素到列表的头部,或者尾部

  • 编码

    • 列表对象的编码可以是ziplist(压缩列表)和linkedlist(双端链表)。
    • 编码转换
      • 同时满足下面两个条件时使用压缩列表:
        • 列表保存元素个数小于512个
        • 每个元素长度小于64字节
      • 不能满足上面两个条件使用linkedlist(双端列表)编码
  • 常用命令

    • lpush: 从头部加入元素
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值