应用场景
- 适合于排行榜类型的业务场景,如音乐榜单:歌曲的点击次数作为score,歌曲名作member值
- 该有序集合中,menber是唯一的,score可重复
存储结构
-
zipList:
当zset满足以下条件时使用次存储:
成员数量小于128个;
每个Member的字符串长度都小于64个字节;
ziplist由五部分组成:每一部分在内存中都是紧密相邻存储的
zlbytes:表示当前ziplist占用的总字节数;
zltail:指示压缩列表尾部元素相对于ziplist起始元素的偏移量;
entry:用来存放具体的数据项----->score & member,长度不定,会根据menber的数量自动扩容;
zllen:指ziplist中entry的个数,;
zlend:起到标识ziplist内存结束点的作用。 -
skiplist:当zset不满足ziplist存储条件时,采用其;
CUID:O(logN);
结构:typedf struct zskiplist{
struct zkiplistNode *Header;//指向跳表zkiplist的头结点,时间复杂度O(1);
struct zkiplistNode *tail//指向跳表的尾结点;
length;//记录跳表中有多少个元素,但不包括头结点;
int level;//记录当前跳表中all节点中的最大层数;
}
跳表的每一层是一个有序链表,最高可达64层,链表中每个节点—>zkiplistNode包含两个指针,一个指向本层中下一个节点,另一个指向下一层的同一个节点(应该是指下一层同一个位置上的?NO!);每个节点都存储着score/member;
注意:最底层的链表将包含zset中的所有元素;如果说一个元素出现在了某一层,那么低于该层的所有层都将包含这个元素,也就说高层是底层的子集.
使用跳跃链表查找S:M节点过程中,从高层—>最底层,会搜索到一系列的期望节点,形成一条搜索路径-------->由每一层的期望节点组成。
命令演示
-
一个保存了员工薪水的有序集合:
-
zadd salary 4000 lucy 5000 tom 5000 helen 6500 jack //key—>salary ;score/member
-
zrange salary 0 3
输出:1)“lucy”
2)“tom”
3)“helen”
4)“jack”
输出指定区间0~3的成员,并按score有序输出 -
zrevrange salary 0 2
输出:1)“jack”
2)“helan”
3)“tom”
降序输出 -
zscore salary lucy
输出:“4000”
查看指定成员的score -
zrange salary 0 3 withscores
查看所有成员和score -
zcount salary 3000 5000
查看指定score范围内的成员个数,3000<=score<=5000 -
zcount salary (3000 (5000
3000<score<5000 -
zrangebyscore salary 3000 5000 withscores limit 1 2
输出:1)“helen”
2)5000.0
3)“tom”
4)5000.0
返回指定范围内的s/m,限制条件:跳过一个元素,返回两个元素。