前言:有序集合zset跟其他类型一样,同样有几种编码方式。主要有两种编码方式,REDIS_ENCODING_ZIPLIST和REDIS_ENCODING_SKIPLIST。ziplist可以表示较小的有序集合, skiplist表示任意大小的有序集合。

  何时用REDIS_ENCODING_ZIPLIST?

  (1)zset会根据zadd命令添加的第一个元素的长度大小来选择编码方式,满足zset_max_ziplist_entries的值不为0,第一个元素的长度小于server.zset_max_ziplist_value,否则就使用skiplist。
  (2)当待新加的新的字符串长度超过zset_max_ziplist_value(默认值64)时或者ziplist保存的节点数量超过server.zset_max_ziplist_entries(默认值128)时使用skiplist。

相关代码一目了然:创建ziplist前面有介绍,在这里不再敖述相关代码在object.c和ziplist.c中。

  if (zobj == NULL) {
if (xx) goto reply_to_client; /* No key + XX option: nothing to do. */
if (server.zset_max_ziplist_entries == ||
server.zset_max_ziplist_value < sdslen(c->argv[scoreidx+]->ptr))
{
zobj = createZsetObject();
} else {
zobj = createZsetZiplistObject();
}
dbAdd(c->db,key,zobj);
} else {
if (zobj->type != OBJ_ZSET) {
addReply(c,shared.wrongtypeerr);
goto cleanup;
}
}

  Skiplist:跳跃表是一种随机化的数据结构,基于链表,其效率可以比拟平衡二叉树,插入、查找、删除都可以在对数期望时间内完成(平均复杂度为O(logN),最坏为O(N)),但是又比平衡树简单直观。

  维基百科提供的Skiplist图:

  

  主要有四部分组成
       A:head:节点指针
       B:node:元素值,每个节点有一层或多层
       C:level: 指向该层下一个节点的指针
       D:tail:全部为null  

Redis的Skiplist代码如下:

/* ZSETs use a specialized version of Skiplists */
typedef struct zskiplistNode {
robj *obj;
double score;
struct zskiplistNode *backward;
struct zskiplistLevel {
struct zskiplistNode *forward;
unsigned int span;
} level[];
} zskiplistNode;
typedef struct zskiplist {
struct zskiplistNode *header, *tail;
unsigned long length;
int level;
} zskiplist; typedef struct zset {
dict *dict;
zskiplist *zsl;
} zset;

  可以清楚的看到redis的skiplist里面多了dict,forward,span几个元素,这三个元素有什么好处呢?
  1、dict维护了skiplist的元素值(key)和分数(value)用于快读的查找元素对应的分值以及判断元素是否存在。
  2、forward前向指针,用于从底层表尾向表头方向遍历。的结构中存在span跨度字段
  3、span存在于forward中,这个跨度字段的出现有助于快速计算元素在整个集合中的排名
  另外redis的跳跃表中,允许重复的score出现,多个不同的元素score值可以相同,若score值相同时,需要对比member,按字典排序存储在跳表结构中。

  相关操作:

  ZADD key score member [[score member] [score member] ...]
  将一个或多个元素以及值加入到有序集中。不存在创建,存在更新。
  ZREM key member [member ...]
  移除一个或这个成员,不存在忽略
  ZCARD key
  返回有序集的基数,不存在返回0
  ZCOUNT key min max
  返回score在min和max之间的成员
  ZSCORE key member
  返回有序集中,成员的score值
  ZINCRBY key increment member
  为有序集的成员的score加上相应的增量,不存在则创建
  ZRANGE key start stop
  根据基数返回有序集key中,指定区间内的成员,score值从小到大排列
  ZREVRANGE key start stop
  根据基数返回有序集key中,指定区间内的成员,score值从大到小排列
  ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
  返回有序集key中,所有score值介于min和max之间的成员。有序集成员按score值从小到大排列
  ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]
  返回有序集key中,所有score值介于min和max之间的成员。有序集成员按score值从大到小排列
  ZRANK key member
  返回有序集key中成员member的排名。有序集成员按score值从小到大排列
  ZREVRANK key member
  返回有序集key中成员member的排名。有序集成员按score值从大到小排列
  ZREMRANGEBYRANK key start stop
  移除有序集key中,指定排名(rank)区间内的所有成员。
  ZREMRANGEBYSCORE key min max
  移除有序集key中,所有score值介于min和max之间的成员。
  ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]
  计算一个或多个有序集的交集,其中给定的key必须以numkeys参数指定,并将该交集储存到destination
  注:结果集中某个成员的score值是所有给定集下该成员score值之和
  ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]
  算给定的一个或多个有序集的并集,其中给定key的数量必须以numkeys参数指定,并将该并集储存到destination
  注:结果集中某个成员的score值是所有给定集
  以上的min和max均包含等于。

Redis数据类型之ZSet(五)的更多相关文章

  1. Redis数据类型介绍

    Redis 数据类型 Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合). String(字符串) st ...

  2. redis数据类型

    Redis 数据类型 Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合). String(字符串) st ...

  3. Redis笔记(二):Redis数据类型

    Redis 数据类型 Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合). String(字符串) st ...

  4. Redis 基础:Redis 数据类型

    Redis 数据类型 Redis支持五种数据类型:string(字符串).hash(哈希).list(列表).set(集合)及zset(sorted set:有序集合). String(字符串) st ...

  5. Redis学习三:Redis数据类型

    一.Redis的五大数据类型 1.String(字符串) string是redis最基本的类型,你可以理解成与Memcached一模一样的类型,一个key对应一个value.string类型是二进制安 ...

  6. Redis数据类型及常用命名总结

    Redis数据类型: Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合).  1.String(字符串) ...

  7. Redis学习笔记(二) Redis 数据类型

    Redis 支持五种数据类型:string(字符串).list(列表).hash(哈希).set(集合)和 zset(有序集合),接下来我们讲解分别讲解一下这五种类型的的使用. String(字符串) ...

  8. redis(一):Redis 数据类型

    Redis 数据类型 Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合). String(字符串) st ...

  9. redis基础:redis下载安装与配置,redis数据类型使用,redis常用指令,jedis使用,RDB和AOF持久化

    知识点梳理 课堂讲义 课程计划 1. REDIS 入 门 (了解) (操作)   2. 数据类型 (重点) (操作) (理解) 3. 常用指令   (操作)   4. Jedis (重点) (操作) ...

随机推荐

  1. Ajax 跨域提交表单

    跨域提交表单,前端ajax不用做任何修改, 只需要在后端调用的方法里面添加一行代码即可. .NET 版 HttpContext.Response.AddHeader("Access-Cont ...

  2. 织梦dedecms单标签、双标签

    标签是dedecms的核心,dedecms的标签也跟html标签一样,同样分单标签和双标签. 我不会讲单标签有那些,双标签有那些,也不会叫大家去背那些是单标签,那些是双标签.如果去背这些标签,这样学起 ...

  3. cookie的路径问题

    今天公司网站(不考虑跨域访问情况)有个需求就是在一个路径下存一个cookie 比如这样 www.fdf.com/vichain/dashback/myback  在这个目录下存放一个cookie 在这 ...

  4. Vue按需加载提升用户体验

    Vue官方文档异步组件: 在大型应用中,我们可能需要将应用拆分为多个小模块,按需从服务器下载.为了让事情更简单, Vue.js 允许将组件定义为一个工厂函数,动态地解析组件的定义.Vue.js 只在组 ...

  5. [HNOI2009]梦幻布丁 算法技巧之邻接链

    题目描述 N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2,2,1的四个布丁一共有3段颜色. 输入输出格式 输入格式: 第 ...

  6. mysql 修改表结构的字段名

    alter table domains  change STATUS  status  tinyint(1)  not null;

  7. Kafka 源代码分析之LogManager

    这里分析kafka 0.8.2的LogManager logmanager是kafka用来管理log文件的子系统.源代码文件在log目录下. 这里会逐步分析logmanager的源代码.首先看clas ...

  8. 8.vue的生命周期

    Vue实例有一个完整的生命周期,也就是从开始创建.初始化数据.编译模板.挂载Dom.渲染→更新→渲染.卸载等一系列过程,我们称这是Vue的生命周期.通俗说就是Vue实例从创建到销毁的过程,就是生命周期 ...

  9. 由于IPv6导致的iOS应用发布失败,是否该怪Azure?

    IPv6已经被越来越广泛的支持了,尤其是苹果强制要求iOS (确切的说是iOS 9以及后续版本)应用必须支持IPv6之后(官方宣布),更将进一步推动IPv6的使用. 不过苹果应用作为客户端强制要求IP ...

  10. 搭建SSM项目框架全过程及思考

    1.前言 之前都是在现有框架下进行写代码或者总是看一些别人的架构,总会眼高手低.于是打算自己完整的走一遍流程,同时把所遇到的问题,思考的问题记下来,供大家参考.由于是工作年限不高,属于新手,不足之处还 ...