Redis——基本数据结构

Redis有5个基本数据结构,string、list、hash、set和zset

一、String

1、底层结构

简单动态字符串(SDS):

/*  
 * 保存字符串对象的结构  
 */  
struct sdshdr {  
      
    // buf 中已占用空间的长度  
    int len;  
  
    // buf 中剩余可用空间的长度  
    int free;  
  
    // 数据空间  
    char buf[];  
};  

                             

特点:(和Java中ArrayList结构很像)

(1)引入了len属性,获取字符串长度的时间复杂度为O(1),防止数组越界。

(2)引入了free属性,自动扩容:

            a)进行修改后len小于1M,程序将分配和len一样大小的free空间

            b)进行修改后len大于1M,程序将分配1M空间

2、基本操作(包含其他基本操作)

默认Redis会创建16个数据库,默认为0号数据库,切换数据库:select 2

set key value//设置键值

get key         //获取值

del key       //删除键

exists key //判断键是否存在

keys pattern //查找符合pattern的key

setnx key value//只有在 key 不存在时设置 key 的值。

 

二、List

1、底层结构

双向链表:

链表节点定义:

typedef struct listNode{
      struct listNode *prev;
      struct listNode * next;
      void * value;  
}

  

链表定义:

ypedef struct list{
    //表头节点
    listNode  * head;
    //表尾节点
    listNode  * tail;
    //链表长度
    unsigned long len;
    //节点值复制函数
    void *(*dup) (void *ptr);
    //节点值释放函数
    void (*free) (void *ptr);
    //节点值对比函数
    int (*match)(void *ptr, void *key);
}

2、基本操作

LPUSH key value1 [value2]  //将一个或多个值插入到列表头部

LPOP key //移出并获取列表的第一个元素

RPUSH key value1 [value2] //将一个或多个值插入到列表尾部

RPOP key //移除列表的最后一个元素,返回值为移除的元素。

BLPOP key1 [key2 ] timeout //移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。

BRPOP key1 [key2 ] timeout //移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。

LLEN key  //获取列表长度

LRANGE key start stop  //获取列表指定范围内的元素

3、应用


1.微博 TimeLine
2.消息队列

三、Hash

1、底层实现

字典(dict):

typedef struct dict {
    // 类型特定函数
    dictType *type;
    // 私有数据
    void *privedata;
    // 哈希表
    dictht  ht[2];
    // rehash 索引
    in trehashidx;

}

解决Hash冲突:链地址法(和JDK1.7的HashMap一样)

rehash:

1)为ht[1]hash表分配空间

              如果执行的是拓展操作,那么ht[1] 的大小为第一个大于等于ht[0] 的2的n次幂

    如果执行的是收缩操作,那么ht[1] 的大小为第一个大于等于ht[0] 的2的n次幂

2)将ht[0]中的数据转移到ht[1]中,在转移的过程中,需要对哈希表节点的数据重新进行哈希值计算

渐进式Hash:并不是一次性转移,而是在每次执行添加等操作时慢慢转移,分摊每次操作成本。

3)将ht[0]释放,然后将ht[1]设置成ht[0],最后为ht[1]分配一个空白哈希表,为下一次rehash准备。

2、基本操作

HSET key field value // 将哈希表 key 中的字段 field 的值设为 value 。

HSETNX key field value //只有在字段 field 不存在时,设置哈希表字段的值。

HMSET key field1 value1 [field2 value2 ] //同时将多个 field-value (域-值)对设置到哈希表 key 中。

HGET key field //获取存储在哈希表中指定字段的值。

HEXISTS key field  //查看哈希表 key 中,指定的字段是否存在.

HDEL key field1 [field2]  //删除一个或多个哈希表字段

HGETALL key //获取在哈希表中指定 key 的所有字段和值

HKEYS key //获取哈希表中所有键

HVALS key //获取哈希表中所有值

HLEN key //获取哈希表大小

3、应用

存储、读取、修改用户属性

四、Set

1、底层实现

字典(dict)

2、基本操作

SADD key member1 [member2]  //向集合添加一个或多个成员

SREM key member1 [member2] //向集合移除一个或多个成员

SMEMBERS key //返回集合中的所有成员

SCARD key //获取集合的成员数

SINTER key1 [key2]  //求交集

SDIFF key1 [key2]  //求差集

SUNION key1 [key2] //求并集

SPOP key //移除并返回集合中的一个随机元素

 

3、应用

1.共同好友、二度好友

2.抽奖
3.利用唯一性,可以统计访问网站的所有独立 IP
4.好友推荐的时候,根据 tag 求交集,大于某个 threshold 就可以推荐

五、ZSet(有序集合)

1、底层实现

跳表(skiplist):

跳表节点结构:

typedef struct zskiplistNode{
   //层
     struct zskiplistLevel{
     //前进指针
        struct zskiplistNode *forward;
    //跨度
        unsigned int span;
    } level[];
  //后退指针
    struct zskiplistNode *backward;
  //分值
    double score;
  //成员对象
    robj *obj;
}

1、层:level 数组可以包含多个元素,每个元素都包含一个指向其他节点的指针。

2、前进指针:用于指向表尾方向的前进指针

3、跨度:用于记录两个节点之间的距离

4、后退指针:用于从表尾向表头方向访问节点

5、分值和成员:跳跃表中的所有节点都按分值从小到大排序。成员对象指向一个字符串,这个字符串对象保存着一个SDS值

跳表结构:

typedef struct zskiplist {
     //表头节点和表尾节点
     structz skiplistNode *header,*tail;
     //表中节点数量
     unsigned long length;
     //表中层数最大的节点的层数
     int level;

}zskiplist;

2、基本操作

ZADD key score1 member1 [score2 member2]  //向有序集合添加一个或多个成员,或者更新已存在成员的分数

ZRANGEBYLEX key min max [LIMIT offset count] //通过字典区间返回有序集合的成员

ZCARD key  //获取有序集合的成员数

ZCOUNT key min max //计算在有序集合中指定区间分数的成员数

ZRANK key member //返回有序集合中指定成员的索引

ZINCRBY key increment member //有序集合中对指定成员的分数加上增量 increment

ZREM key member [member ...] //移除有序集合中的一个或多个成员

ZSCORE key member //返回有序集中,成员的分数值

3、应用

带有权重的元素,比如一个游戏的用户得分排行榜

补充:当数据较少时,Redies内部用ziplist结构来实现list、hash、set和zset

示例:

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值