重修Redis一:五种常见的数据类型及使用场景

为什么会选择Redis?

    Redis是C语言开发的内存数据库,作为时下最常用的非关系型数据库之一,为什么会有如此多的公司选择Readis?主要包括一下几点:

  1. 丰富的数据类型,包括String,List,Hash,Set,zSet,根据不同的场景选择更适用的数据类型;

  2. 性能优势:数据存在内存,读写速度快,支持可达10W QPS;

  3. 高可用:支持主从复制,哨兵监听,集群部署;

  4. 安全性:单线程,线程安全,采用IO多路复制机制;

  5. 数据可靠性:数据可持久化到磁盘,重启后可重新加载到内存。

数据类型和数据结构

       Redis构建了自己的对象系统,这个对象系统中包括常用的五种数据结构:String、Hash、List、Set、zSet。Redis的每个对象都是由一个redisObject结构表示:

typedef struct redisObject{

   //类型
   unsigned type:4;
  //编码
  unsigned encoding:4;
  //指向底层实现数据结构的指针
  void *ptr;
  //...
}rojg;

     其他对象类型就包括:String、Hash、List、Set、zSet编码和指向指定了以上5种常用的数据类型底层的实现的数据结构:

  

五种的常用的数据类型:

    Redis的数据存储格式都是key- value的形式存在的。

String

简介:

      String是最基本的数据类型,而且是二进制安全的,String可以包含所有格式的数据,包括字符串,数字,JPG图片等,最大存储可以是1G。这里和Memcached基本是一模一样的类型。

常用的命令包括:


get key value,获取key对应的字符串,如果不存在,返回nil

set key value,设置key对应类型的String类型数据,成功返回1,失败返回0;

decr key,对key的值做--操作,decr一个不存在的key,则设置key值为-1;

incr key,对key的值做++操作,返回一个新的值,需要注意的是incr一个不是int类型的value会报错,incr一个不存在的值会返回1;

mget  key1,key2.....keyN,一次获取多个key的值,如果对应的key不存在,则返回nil;

mset key1 value1;key2 value2......keyN valueN,一次设置多个key的值,如果全部成功返回1,如果返回0,表示一个都没有设置成功。

适用场景:

     存储简单类型的数据,比如计数等功能。

实现原理:

     Redis字符串由动态字符串SDS其实是函数实现,函数中记录了字符串的长度,未使用字节长度,和保存字符串的数据

struct sdshdr{
    //记录bus数组中已使用的字节长度
    //等于SDS所保存字符串长度
    int len;
    //记录buf数组中未使用字节的数量
    int free;
    //字节数组,用于保存字符串
    char buf[];

}

 

优势:

  1. SDS本身保存字符串长度,提高效率:C本身获取字符串需要变量获取字符串长度需要整理遍历字符串,时间复杂度为O(n),SDS将字符串长度作为本身的属性,时间复杂度为O(1);
  2. 杜绝缓冲区溢出:C本身不记录自身长度,除非分配了足够的内存,否则在修改字符串时会产生缓冲区溢出的问题。而SDS的分配策略是在修改字符串长度时会首先检查字符串长度是否满足,如果的不满足,会先扩展SDS的空间,从而杜绝异常;
  3. 减少字符串修改时带来的内存重分配次数:在C中字符串重复修改会造成频繁的执行内存重分配操作,可能会对性能造成影响,SDS为了解决这缺陷,实现了空间预分配的机制,简单来说就是在对SDS进行空间扩展时不仅会分配必要的空间,还会分配额外的使用空间,用free表示。空间界限为1MB,如果修改后的len小于1MB,那么会分配同样大小的未使用空间,此时len和free的值相同;如果大于1MB,则会分配1MB的未使用空间。
  4. 惰性空间释放:当字符串缩短时,并不会将缩短的空间立即释放,而时将空间长度暂存free,已备下次使用。同时在需要时也有API提供去释放SDS未使用的空间。
  5. 二进制安全存储:C字符串中只能保存文本数据,不支持图片,音频等数据,而SDS已二进制处理buf数据,来支持其他数据的存储,从而达到存储,保护数据的目的,同时也兼容了C字符串以及C的部分函数。

List:

简介:

      List是由双端链表实现的字符串列表,每一个子元素都是String类型,按照插入顺序排序,每一个key都是链表的名字。

//节点结构
typedef struct listNode{
  //前躯节点
  struct listNode*prev;
  //后继节点
  struct listNode*next;
  //节点的值
  void*value;
}

常用命令包括:

lpush key value  在key对应的list头部添加字符串元素,1表示添加成功,0表示key存在且不是list类型;

rpush key value 在key对应的list尾部添加字符串元素;

lpop key value   从list的头部开始删除元素并返回删除元素,如果key对应的list不存在或者为空返回nil,如果key对应不是list返回报错;

rpop key value 从list的尾部开始删除元素并返回删除元素,如果key对应的list不存在或者为空返回nil,如果key对应不是list返回报错;

lrange key start end  返回区间内的指定元素,下标从0开始,负值从尾部开始计算,-1表示最后一个元素,不存在返回空列表;

适用场景:

     粉丝列表等列表类数据,发布、订阅的中间件

优势特点:

  1. 获取某个节点的前驱节点和后继节点的复杂度都是O(1);
  2. 双向链表的头尾节点都是null,可以判断头尾节点
  3. 带有链表长度的技术器
  4. 可以用于保存不同的数据类型

Hash

简介:

      Hash 是一个键值(key-value)的集合。readis的 hash 是一个 string 的 key 和 value 的映射表,Hash 特别适合存储对象。

//节点结构
typedef struct listNode{
  //前躯节点
  struct listNode*prev;
  //后继节点
  struct listNode*next;
  //节点的值
  void*value;
}

常用命令包括:

hget key field value 设置hash fied为指定的值,如果key不存在,则创建;

hset key field  获取指定的hash fied

hgetall 返回Hash所有的key 和value

适用场景:

     Hash由于适合存储对象,在数据范围更广,可以用来存储用户信息,商品信息等

优势:

  1. 相比String,hash占用更少的内存,存取整个对象更方便
  2. 省内存的原因:新建hash对象时先开始用zipmap来存储,会节省Hash一些本身元素数据的存储开销,当filed和value超过一定限制后,readis会将zipmap转换成正常的Hash实现,这个限制可以在配置文件中指定:

        hash-max-zipmap-entries 64              #配置字段最多64个

        hash-max-zipmap-value 512              #配置value最大为512个字节

set

简介:

      set是存储String类型的无序集合,通过hashtable实现,set存储的元素是没有顺序且不可重复的。

常用命令包括:

sdd key member 添加一个String元素到key对应的set集合中,成功返回1,如果元素在集合中则返回0,key对应的set不存在则返回错误;

spop key  删除并返回key对应set中随机的一个元素,如果set是空或者key不存在返回nil;

smembers  key 返回key在set中所有元素,结果是无序的;

sunion key1 key2 .....keyN 返回所有指定key的交集

适用场景:

    可以对标list的适用场景,特殊之处是元素是不可重复的,共同好友等

优势:

      set存储的是不可重复的元素,最大元素支持(2的32次方-1)个元素,由于是hash table实现,所以添加和删除元素,查询元素的时间复杂度都是O(1),hash table 会随着元素的增删自动调整大小,需要注意的是在调整大小时需要同步会阻塞其他读写(3.0之前的版本)除了常规操作,还是支持取并集,交集,差集等。

zSet

简介:

    内部数据结构sorted set ,和set的指令集基本一致,但是插入的元素是不可重复的且有序。

常用命令包括:

zadd  key score member  添加元素到集合,元素在集合中存在则更新对应的score;

zrange key start end 类似lrange的操作从集合指定去取指定区间的元素,返回是有序的结果

zrem key member 删除指定元素,1表示成功,如果元素不存在返回0;

zcard key 返回集合中元素的个数。

适用场景:

     获取排行榜,有权重的消息队列。

优势:

    sorted set 的内部使用 HashMap 和跳跃表(skipList)来保证数据的存储和有序,HashMap 里放的是成员到 score 的映射,而跳跃表里存放的是所有的成员,排序依据是 HashMap 里存的 score,使用跳跃表的结构可以获得比较高的查找效率,并且在实现上比较简单。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值