Redis中存在五种值类型,分别是string(字符串),list(列表),hash(散列),set(集合)和sorted set(有序集合)。下面我们对每一种值类型进行分析理解。

RedisObject

在介绍redis值类型之前,我们得先了解一下redisObject。redisObject是redis中封装value对象的数据结构。任何一个value都会被包装成一个redisObject。redisObject能指定value的类型,编码格式,内存回收,数据指针等。这样设计的好处是在5种常用类型设置多种不同的的数据结构实现,优化对象在不同场景下的效率。

typedef struct redisObject {
    // 刚刚好32 bits
    // 对象的类型,字符串/列表/集合/哈希表
    unsigned type:4;
    // 未使用的两个位
    unsigned notused:2; /* Not used */
    // 编码的方式,Redis 为了节省空间,提供多种方式来保存一个数据
    // 譬如:“123456789” 会被存储为整数123456789
    unsigned encoding:4;
    // 当内存紧张,淘汰数据的时候用到
    unsigned lru:22; /* lru time (relative to server.lruclock) */
    // 引用计数
    int refcount;
    // 数据指针
    void *ptr;
} robj

这里介绍几个比较关键的属性:

  • type:标记了value对象的数据类型,使用type 命令来获取。所有数据类型如下所示:

    /* Object types */
    #define REDIS_STRING 0
    #define REDIS_LIST   1
    #define REDIS_SET    2
    #define REDIS_ZSET   3
    #define REDIS_HASH   4
  • encoding:标记了value对象的编码,也就是使用了什么数据结构,使用 object encoding 命令来获取。编码如下所示:
/* Objects encoding. Some kind of objects like Strings and Hashes can be
* internally represented in multiple ways. The 'encoding' field of the object
* is set to one of this fields for this object. */
#define REDIS_ENCODING_INT  /* Encoded as integer */
#define REDIS_ENCODING_EMBSTR  /* Encoded as embstr */
#define REDIS_ENCODING_RAW  /* Raw representation */
#define REDIS_ENCODING_HT  /* Encoded as hash table */
#define REDIS_ENCODING_LINKEDLIST  /* Encoded as regular linked list */
#define REDIS_ENCODING_ZIPLIST  /* Encoded as ziplist */
#define REDIS_ENCODING_INTSET  /* Encoded as intset */
#define REDIS_ENCODING_SKIPLIST  /* Encoded as skiplist */    

redis为优化内存,对数据类型提供了多种底层实现方式,type和encoding对应关系如下表格所示:

类型(type属性)编码(encoding属性)注释
REDIS_STRINGREDIS_ENCODING_INT整数值实现的字符串
REDIS_STRINGREDIS_ENCODING_EMBSTRembstr编码的简单动态字符串实现的字符串
REDIS_STRINGREDIS_ENCODING_RAW简单动态字符串实现的字符串
REDIS_LISTREDIS_ENCODING_ZIPLIST压缩列表实现的列表
REDIS_LISTREDIS_ENCODING_LINKEDLIST双向链表实现的列表
REDIS_HASHREDIS_ENCODING_ZIPLIST压缩列表实现的哈希表
REDIS_HASHREDIS_ENCODING_HT字典实现的哈希表
REDIS_SETREDIS_ENCODING_INTSET整数集合实现的集合
REDIS_SETREDIS_ENCODING_HT字典实现的集合
REDIS_ZSETREDIS_ENCODING_ZIPLIST压缩列表实现的有序集合
REDIS_ZSETREDIS_ENCODING_SKIPLIST使用跳跃表+字典实现的有序集合
  • lru:redis对数据集占用内存的大小由周期性的计算,当超出限制时,会淘汰超时的数据。即淘汰的标准为:oversize & overtime。

举个栗子,当set hello world时会有以下数据模型:
image.png

  • dictEntry:Redis给每个key-value键值对分配一个dictEntry,里面有着key和val的指针,next指向下一个dictEntry形成链表,这个指针可以将多个哈希值相同的键值对链接在一起,由此来解决哈希冲突问题(链地址法)。
  • sds:键key "hello" 是以SDS(简单动态字符串)存储。
  • redisObject值val是存储在redisObject。
简单动态字符串:长度动态可变,可类比为Java中的ArrayLIst。Redis中不仅Key是以SDS形式存储,String类型value对象也有以SDS存储。
struct sdshdr {
    int len;  // buf数组中已经使用的字节的数量,也就是SDS字符串长度
    int free; // buf数组中未使用的字节的数量  
    char buf[];  // 字节数组,字符串就保存在这里面
};
  • 常数复杂度获取字符串长度:len字段存储字符串长度
  • 预空间分配:

    • SDS长度(len的值)小于1MB,那么程序将分配和len属性同样大小的未使用空间,这时free和len属性值相同。
    • SDS长度(len的值)大于等于1MB,程序会分配1MB的未使用空间。
  • 惰性释放空间:当执行sdstrim(截取字符串)之后,SDS不会立马释放多出来的空间,如果下次再进行拼接字符串操作,且拼接的没有刚才释放的空间大,则那些未使用的空间就会排上用场。通过惰性释放空间避免了特定情况下操作字符串的内存重新分配操作。
  •  杜绝缓冲区溢出:使用C字符串的操作时,如果字符串长度增加(如strcat操作)而忘记重新分配内存,很容易造成缓冲区的溢出;而SDS由于记录了长度,相应的操作在可能造成缓冲区溢出时会自动重新分配内存,杜绝了缓冲区溢出。

    String

    String类型是我们最常用的一种value数据类型,在上文中我们看到string的encoding有三种类型,即对应的三种数据结构实现(int,embstr,raw)。embstr和raw都是SDS存储(上文已介绍),但embstr只需要一次内存分配空间,而raw需要两次。
    int编码字符串对象和embstr编码字符串对象在一定条件下会转化为raw编码字符串对象。如下所示:
    image.png

image.png
当你存储的是中文时,由于redis是二进制安全的,所以在不同编码下数据的长度是不同的,有兴趣的可以看看这篇文章redis是二进制安全

字符串

String数据类型中比较常用的就是作为字符串使用,可以作为缓存存储一些信息,比如登录用户的一些信息等。如果对命令不太熟悉的前提下我们在Linux系统中可以在连接redis客户端的前提下使用help @String 来获取各个命令的作用和语法或者在redis命令中心查看。

API

作为字符串常用的命令包括以下:

## ex(秒) 和 px(毫秒) 表示key的过期时间  nx 表示不存在才操作 xx表示存在才操作
SET key value [EX seconds|PX milliseconds] [NX|XX] [KEEPTTL]
summary: Set the string value of a key
since: 1.0.0

## set 多个 key value
MSET key value [key value ...]
summary: Set multiple keys to multiple values
since: 1.0.1

## 在原value后追加字符串
APPEND key value
summary: Append a value to a key
since: 2.0.0

## 在value的某个偏移量上重写新的value值
SETRANGE key offset value
summary: Overwrite part of a string at key starting at the specified offset
since: 2.2.0

## 获取value的值长度
STRLEN key
summary: Get the length of the value stored in a key
since: 2.2.0

## 获取旧值并设置新值
GETSET key value
summary: Set the string value of a key and return its old value
since: 1.0.0

数值

当作为数值使用时,其操作都是原子性,故可以作为规避并发的一种手段,其应用场景包括 秒杀、点赞、收藏,抢购等。

API

作为数值常用的命令如下:

## value + 1
INCR key
summary: Increment the integer value of a key by one
since: 1.0.0

## value - 1
DECR key
summary: Decrement the integer value of a key by one
since: 1.0.0

## value + increment
INCRBY key increment
summary: Increment the integer value of a key by the given amount
since: 1.0.0

## value - increment
DECRBY key decrement
summary: Decrement the integer value of a key by the given number
since: 1.0.0

## value + increment (浮点型)
INCRBYFLOAT key increment
summary: Increment the float value of a key by the given amount
since: 2.6.0

bitmap

bitmap不是实际的数据类型,而是在String类型上定义的一组面向位的操作。根据官方给出的文档提示,位图最大的优势就是在存储时能节省大量空间。其常用的应用场景包括统计活跃用户或用户登录天数等。

API

## 统计key从start到end的被设置的为1的bit数  start end 是字节索引
BITCOUNT key [start end]
summary: Count set bits in a string
since: 2.6.0

## 设置或者清空key的value(字符串)在offset处的bit值 offset 为二进制的索引
SETBIT key offset value
summary: Sets or clears the bit at offset in the string value stored at key
since: 2.2.0

## 返回位图中第一个值为 bit(0或1) 的二进制位的位置 start end 是字节索引
BITPOS key bit [start] [end]
summary: Find first bit set or clear in a string
since: 2.8.7

## 对一个或多个保存二进制位的字符串 key 进行位元操作,并将结果保存到 destkey 上
## operation 可以是 AND(并)、OR(或)、NOT(非)、XOR(异或)这四种操作中的任意一种
## 当key不同长度 较短的那个key默认以0补位
BITOP operation destkey key [key ...]
summary: Perform bitwise operations between strings
since: 2.6.0

## 参考 http://redis.cn/commands/bitfield.html
BITFIELD key [GET type offset] [SET type offset value] [INCRBY type offset increment] [OVERFLOW WRAP|SAT|FAIL]
summary: Perform arbitrary bitfield integer operations on strings
since: 3.2.0

这里对bitmap进行简单演示:
image.png
分别在key为bit的二进制索引位置1和二进制位置7设置为1,这样实际上就是01000001 根据ASCII编码该值就是A。
image.png
上图表示有2个位被设置为1,当添加start 和 end参数时 该值表示字节索引,如下所示:
image.png
首先在第二进制索引位置16设置为1 即 01000001 00000000 10000000 当统计第1个字节到第2个字节的被设置为1的数量时则是2个,当不添加则表示所有字节上述实例就是3个。
image.png
首先在二进制索引5设置为1 即 00000100 ,然后分别获取第一个为0和第一个为1的索引位置;然后再二进制索引8设置1 即 00000100 10000000 ,当设置start 和 end时 该值表示字节索引 开始索引分别从第一个字节和第二个字节开始 ,结果即为 5 和 8。

应用场景

用途我们在上面介绍时分别都有提及到,不过作为字符串和数值的用途比较常见,此处不做撰述。我们来仔细看看作为bitmap时的应用场景如何使用。
首先就是统计用户登录天数。假设你用关系型数据库去处理,每个用户登录一天你有相关的登录记录表去录,如果你有1千万的活跃用户每天都在登录你的系统那么你每个人都去记录一条数据,一年365天光数据存储都占用了非常多的资源。如果是使用bitmap你可以这样做,登录人的id作为key,每一位表示一天,即如下表。(1表示登录过 ,0表示未登录)

用户\天数12345...364365
userId101101...01
userId211011...10
...........................
userId9911110...11

当用户登录使用setbit userId offset(哪一天)1 就可以记录该用户当天登录,然后使用bitcount 即可以得出用户登录天数,或者你需要获取某个时间周期内的登录天数只要在bitcount加上startend 即可,最最重要的是它占用的空间非常少比起关系型数据库少太多。

其次就是活跃用户统计,比如你要统计日🔥用户,那么你也可以使用bitmap来做,思路和上面差不多,只不过现在是把日期作为key,用户的id映射为位,即如下表。(1表示活跃,0表示不活跃)

日期\用户12345...364365
2020081801101...01
2020081911010...11

当用户活跃时,使用setbit 20200818 offset(用户id映射的位)1 即表示用户活跃,然后使用bitcount即可以得出当天的活跃用户;如果你需要对某个时间周期内进行统计且需要去重则可使用bitop or destkey 时间key1 时间key... 然后再对destKey进行bitcount 即可。

假设每个用户存储需要20B空间, 那么1亿个用户所占用的空间就是 20 * 100000000 = 20000000000B ≈ 18G,看起来也是个不小的内存消耗;如果你对精确度不是很高的要求那么可以考虑Redis提供的Hypeloglog,可以参考下 Redis HyperLogLog介绍及应用

List

List数据类型就是有序(插入顺序)元素的序列,其对应的encoding为上文表格中的ziplist和linkelist。Redis中的列表支持两端插入和弹出,并且可指定位置获取元素,可以充当数组,队列,栈等。因此,其应用场景包括微博的时间轴列表,阻塞队列等。

这里不对底层数据结构进行分析,若想了解zipList和linkedList可参考 Redis为何这么快--数据存储角度的List篇。

API

常用的命令如下:

## 获取列表index的值(从左开始)
LINDEX key index
summary: Get an element from a list by its index
since: 1.0.0

## 列表插入某个元素 
LINSERT key BEFORE|AFTER pivot value
summary: Insert an element before or after another element in a list
since: 2.2.0

## 获取列表长度
LLEN key
summary: Get the length of a list
since: 1.0.0

## 从列表左侧弹出(删除并获取)
LPOP key
summary: Remove and get the first element in a list
since: 1.0.0

## 从列表左侧插入多个元素
LPUSH key value [value ...]
summary: Prepend one or multiple values to a list
since: 1.0.0

## 当列表存在时 插入元素
LPUSHX key value
summary: Prepend a value to a list, only if the list exists
since: 2.2.0

## 获取列表指定范围的元素值 start和end为元素索引
LRANGE key start stop
summary: Get a range of elements from a list
since: 1.0.0

## 移除列表count数量的value元素 (从左开始) count为0表示全删 
LREM key count value
summary: Remove elements from a list
since: 1.0.0

## 设置列表index下的值(从左开始)
LSET key index value
summary: Set the value of an element in a list by its index
since: 1.0.0

## 截取列表指定范围的list start和end为元素索引
LTRIM key start stop
summary: Trim a list to the specified range
since: 1.0.0

## 右侧弹出 左侧插入 source 和 destination 都为列表 可为同一个
RPOPLPUSH source destination
summary: Remove the last element in a list, prepend it to another list and return it
since: 1.2.0

以上罗列的是从list的左侧开始,同样的redis也提供了从list的右侧开始。redis同样提供了阻塞式的一些命令。如下所示:

## 阻塞获取列表元素并删除(左侧) 可指定多个列表 同时可设置timeout时间(单位秒)
BLPOP key [key ...] timeout
summary: Remove and get the first element in a list, or block until one is available
since: 2.0.0

## 阻塞获取列表元素并删除(右侧) 可指定多个列表 同时可设置timeout时间(单位秒)
BRPOP key [key ...] timeout
summary: Remove and get the last element in a list, or block until one is available
since: 2.0.0

## RPOPLPUSH source destination 阻塞版本 timeout时间(单位秒)
BRPOPLPUSH source destination timeout
summary: Pop a value from a list, push it to another list and return it; or block until one is available
since: 2.2.0

这里要注意的是当有多个连接对同一个list进行阻塞监听时,redis的处理方法是维护了一个阻塞队列,提供先阻塞先服务,当多个阻塞同时满足唤醒条件时,先阻塞的优先唤醒。

应用场景

上面我们说List可以充当栈,队列。栈的特征是先进后出,那么在使用Redis的同一个方向命令(lpush lpop)时就可以实现栈的特点;队列的特征是先进先出,那么同样的在使用Redis的反向命令(lpush rpoprpush lpop )时就可以实现队列的特点。
微博的时间轴列表也比较简单,每次新增一个微博时只需要lpush 进去即可,通过lrange 来获取最新的微博消息。
阻塞队列的实现就需要使用blpopbrpop ,首先一定要先调用blpop 监听,然后再另外一个客户端进行lpush 操作,如果先lpushblpop 那么先lpush 的数据就不会被监听到。

Hash

Hash数据类型就是 key-value 键值对,对应的encoding可以是ziplist或者hashtable。 Hash对象只有同时满足下面两个条件时,才会使用ziplist(压缩列表):1.哈希中元素数量小于512个;2.哈希中所有键值对的键和值字符串长度都小于64字节。这样会非常节约内存。其应用场景包括点赞,收藏等

对其数据结构有兴趣的仍然可以了解Redis为何这么快--数据存储角度的Hash篇。

API

常用的命令如下:

## 设置多个键值对
HSET key field value [field value ...]
summary: Set the string value of a hash field
since: 2.0.0

## 设置键值对 不存在才设置
HSETNX key field value
summary: Set the value of a hash field, only if the field does not exist
since: 2.0.0

## 设置多个键值对 4.0被弃用
HMSET key field value [field value ...]
summary: Set multiple hash fields to multiple values
since: 2.0.0

## 获取key下某个键对应的值
HGET key field
summary: Get the value of a hash field
since: 2.0.0

## 获取key下多个键对应的值
HMGET key field [field ...]
summary: Get the values of all the given hash fields
since: 2.0.0

## 获取所有key-value键值对
HGETALL key
summary: Get all the fields and values in a hash
since: 2.0.0

## 获取所有的键
HKEYS key
summary: Get all the fields in a hash
since: 2.0.0

## 获取所有的值
HVALS key
summary: Get all the values in a hash
since: 2.0.0

## hash下键所对应的值加 increment值
HINCRBY key field increment
summary: Increment the integer value of a hash field by the given number
since: 2.0.0

## hash下键所对应的值加 increment值(浮点)
HINCRBYFLOAT key field increment
summary: Increment the float value of a hash field by the given amount
since: 2.6.0

## 迭代hash下匹配pattern的键 count指定个数 cursor表示从第几个开始
HSCAN key cursor [MATCH pattern] [COUNT count] 
summary: Incrementally iterate hash fields and associated values
since: 2.8.0

应用场景

Hash的数据类型可以用作点赞,收藏,阅读数等。比如你有一个帖子,你需要为它统计点赞,收藏,阅读。如果你使用string类型的话 你肯定是要设置3个key分别对应点赞,收藏,阅读,这样在无形中也浪费了存储空间;但是如果你使用hash的话 一个key就搞定,使用hset 帖子id 点赞数 0 收藏数 0 阅读 0 ,当每增加一个变化时 使用HINCRBY key field increment 对field进行数值计算就可以解决。
其次就是当你缓存一些数据时,比如说用户如果你使用string缓存,那么必然是个json对象,当你只需要某个值时你需要把整个对象取出来然后处理,但hash就可以直接取出对应的值。

Set

Set是String的无序去重排列,对应的encoding是intset(整数集合)或hashtable。intset(整数集合)当一个集合只含有整数,并且元素不多时会使用intset(整数集合)作为Set集合对象的底层实现。其应用场景包括共同关注,随机事件等。

API

其常用的命令如下所示:

# 集合内操作
## 添加元素
SADD key member [member ...]
summary: Add one or more members to a set
since: 1.0.0

## 集合大小
SCARD key
summary: Get the number of members in a set
since: 1.0.0

## 随机获取集合内count个元素 
## count为正 取出一个去重的结果集
## count为负 取出一个不去重的结果集
## 
SRANDMEMBER key [count]
summary: Get one or multiple random members from a set
since: 1.0.0

## 随机弹出(获取并删除)集合内count个元素
SPOP key [count]
summary: Remove and return one or multiple random members from a set
since: 1.0.0

## 取出所有元素
SMEMBERS key
summary: Get all the members in a set
since: 1.0.0

## 判断member是否在集合中
SISMEMBER key member
summary: Determine if a given value is a member of a set
since: 1.0.0

## 移除元素
SREM key member [member ...]
summary: Remove one or more members from a set
since: 1.0.0

# 集合间操作
## 集合间差集
SDIFF key [key ...]
summary: Subtract multiple sets
since: 1.0.0

## 集合间差集并存储到destination
SDIFFSTORE destination key [key ...]
summary: Subtract multiple sets and store the resulting set in a key
since: 1.0.0

## 迭代集合下匹配pattern的键 count指定个数 cursor表示从第几个开始
SSCAN key cursor [MATCH pattern] [COUNT count]
summary: Incrementally iterate Set elements
since: 2.8.0

## 集合间交集
SINTER key [key ...]
summary: Intersect multiple sets
since: 1.0.0

## 集合间交集并存储到destination
SINTERSTORE destination key [key ...]
summary: Intersect multiple sets and store the resulting set in a key
since: 1.0.0

## 集合间并集
SUNION key [key ...]
summary: Add multiple sets
since: 1.0.0

## 集合间并集并存储到destination
SUNIONSTORE destination key [key ...]
summary: Add multiple sets and store the resulting set in a key
since: 1.0.0

## 把member从source集合移动到destination集合
SMOVE source destination member
summary: Move a member from one set to another
since: 1.0.0

应用场景

Set的应用场景包括随机事件,公共好友。这其实就对应了Set的集合内命令和集合间命令。集合内命令的spop keysrandmember key count 就可以应对随机事件,比如抽奖系统,key为奖品,member为用户id,如果希望中奖的人不会再中就可以使用spop,如果希望重复中奖就可以使用srandmember ;集合间命令获取交集sinter 就可以应对共同好友,共同关注,key为用户,member分别为用户的关注。

Sorted Set

Sorted Set是在Set上添加一个分数(score)维度的集合,通过分数来为集合中的元素进行排序。相比于Set来说Sorted Set可理解为一个有序无重复的序列,其encoding为ziplist或skiplist。当一个有序集合的元素数量比较多或者成员是比较长的字符串时,Redis就使用skiplist(跳跃表)作为ZSet对象的底层实现。其应用场景主要包括排行榜等。

API

常用命令如下:

## 添加集合元素 NX 不更新 只添加 XX只更新 不添加 CH 返回值为修改总数(默认是新增总数) INCR 分值添加
ZADD key [NX|XX] [CH] [INCR] score member [score member ...]
summary: Add one or more members to a sorted set, or update its score if it already exists
since: 1.2.0

## 删除集合元素
ZREM key member [member ...]
summary: Remove one or more members from a sorted set
since: 1.2.0

## 指定分数区间删除集合元素
ZREMRANGEBYSCORE key min max
summary: Remove all members in a sorted set within the given scores
since: 1.2.0

## 指定成员区间删除集合元素 
ZREMRANGEBYLEX key min max
summary: Remove all members in a sorted set between the given lexicographical range
since: 2.8.9

## 指定排名区间删除集合元素
ZREMRANGEBYRANK key start stop
summary: Remove all members in a sorted set within the given indexes
since: 2.0.0

## 获取集合元素分数
ZSCORE key member
summary: Get the score associated with the given member in a sorted set
since: 1.2.0

## 增加集合元素分数
ZINCRBY key increment member
summary: Increment the score of a member in a sorted set
since: 1.2.0

## 返回集合个数
ZCARD key
summary: Get the number of members in a sorted set
since: 1.2.0

## 返回元素排名 默认升序
ZRANK key member
summary: Determine the index of a member in a sorted set
since: 2.0.0

## 返回元素排名 降序
ZREVRANK key member
summary: Determine the index of a member in a sorted set, with scores ordered from high to low
since: 2.0.0

## 指定元素索引返回集合值 WITHSCORES表示是否带分值 升序
ZRANGE key start stop [WITHSCORES]
summary: Return a range of members in a sorted set, by index
since: 1.2.0

## 根据元素分值大小返回集合值 WITHSCORES表示是否带分值 LIMIT 指定索引和数量 升序
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
summary: Return a range of members in a sorted set, by score
since: 1.0.5

## 指定元素索引返回集合值 WITHSCORES表示是否带分值 降序
ZREVRANGE key start stop [WITHSCORES]
summary: Return a range of members in a sorted set, by index, with scores ordered from high to low
since: 1.2.0

## 指定元素分值大小返回集合值 WITHSCORES表示是否带分值 LIMIT 指定索引和数量 降序
ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]
summary: Return a range of members in a sorted set, by score, with scores ordered from high to low
since: 2.2.0

## 指定元素区间返回集合值 LIMIT 指定索引和数量 降序
ZREVRANGEBYLEX key max min [LIMIT offset count]
summary: Return a range of members in a sorted set, by lexicographical range, ordered from higher to lower strings.
since: 2.8.9

## 根据分数区间返回集合元素数量
ZCOUNT key min max
summary: Count the members in a sorted set with scores within the given values
since: 2.0.0

## 返回成员区间返回集合元素数量
ZLEXCOUNT key min max
summary: Count the number of members in a sorted set between a given lexicographical range
since: 2.8.9

## 返回集合下成员在min到max的数量 Limit 指定索引和数量
ZRANGEBYLEX key min max [LIMIT offset count]
summary: Return a range of members in a sorted set, by lexicographical range
since: 2.8.9

## 弹出集合中分数最低元素
ZPOPMIN key [count]
summary: Remove and return members with the lowest scores in a sorted set
since: 5.0.0

## 弹出集合中分数最高元素
ZPOPMAX key [count]
summary: Remove and return members with the highest scores in a sorted set
since: 5.0.0

## 集合间并集 WEIGHTS 使用聚合函数前的乘法因子 AGGREGATE 指定聚合方式
ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]
summary: Add multiple sorted sets and store the resulting sorted set in a new key
since: 2.0.0

## 集合间交集 WEIGHTS 使用聚合函数前的乘法因子 AGGREGATE 指定聚合方式
ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]
summary: Intersect multiple sorted sets and store the resulting sorted set in a new key
since: 2.0.0

## 按照参数中key的顺序,返回第一个非空key中分数最大的成员和对应的分数 timeout为阻塞时间 单位秒
BZPOPMAX key [key ...] timeout
summary: Remove and return the member with the highest score from one or more sorted sets, or block until one is available
since: 5.0.0

## 按照参数中key的顺序,返回第一个非空key中分数最小的成员和对应的分数 timeout为阻塞时间 单位秒
BZPOPMIN key [key ...] timeout
summary: Remove and return the member with the lowest score from one or more sorted sets, or block until one is available
since: 5.0.0

## 迭代集合下匹配pattern的键 count指定个数 cursor表示从第几个开始
ZSCAN key cursor [MATCH pattern] [COUNT count]
summary: Incrementally iterate sorted sets elements and associated scores
since: 2.8.0

应用场景

Sorted Set最常见的应用场景便是排行榜,使用zadd key score member 就可以实现自动排序,默认按照从小到大排序,如果你希望倒序那就使用zrevrangebyscore 根据分数倒序即可,想获取某一个元素的排名使用zrank ,但要记住这仍是正序的,因为sorted set物理内存不随命令变化,想要倒序的排名使用zrevrank

参考链接

Redis源码研究之redisObject
总结redis中对象的类型与编码
Redis为何这么快--数据存储角度


Ekko
2 声望0 粉丝