redis--2

本文介绍了Redis中各种数据类型的使用,包括键的命名规范、自增ID的生成、字符串类型的序列化方法以及位操作命令。接着讨论了散列类型、列表类型、集合类型和有序集合类型的特性和常用命令,如HSET、LPUSH/RPOP、SADD、SREM等,并展示了如何进行交集、并集、差集操作。文章还强调了不同类型在不同场景下的适用性,如列表类型适合存储日志,有序集合类型适用于需要按分数排序的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

redis学习第二章
实践

  1. 键的命名
    redis对于键的命名并没有强制的要求,但比较好的实践是用“对象类型:对象ID:对象属性”来命名一个键,如用键user:1:friends来存储ID为1的用户的好友
  2. 自增id
    在redis中可以生成一个users:count的键来存储当前类型对象的数量,每增加一个对象都使用INCR命令递增该键的值。由于使用INCR命令建立的键的初始键值为1,所以很容易得知,incr命令后返回的即是加入该对象的当前类型的总数,又是该新增对象的ID。
  3. 数据存储(字符串类型)
    由于每个字符串类型的键只能存储一个字符串,而我们要存储的数据可能有多个属性,以博文为例:标题、正文、作者、发布时间等多个属性构成。为了存储这些元素,我们需要序列化函数(如PHP的serialize和JavaScript的JSON.stringify)将他们转换成一个字符串,除此之外,我们也可以使用MessagePack(http://msgpack.org 与json一样可以将对象序列化字符串,但是结果是二进制,所以占用空间更小,性能更高)进行序列化,速度更快,占用空间也更小
  4. 其他基本命令
1:添加指定数值
INCRBY key increment

incrby 命令与 incr 命令基本一样,只不过前者可以通过increment参数指定一次性增加多少个数值
redis > incrby key 2
(integer) 2
redis > incrby key 3
(integer) 5

2:减少数值
DECR key
DECRBY key decrement

DECR命令与INCR命令用法相同,只不过该命令是让键值递减

3:添加浮点数
INCRBYFLOAT key increment

INCRBYFLOAT命令与INCR命令类似,只不过前者可以递增一个双精度浮点数,如:
redis > incrbyfloat key2.7
“7.7”//注意 此时使用incr 会报错

4:向尾部追加值
APPEND key value

APPEND作用是向键值的末尾追加value。如果键值不存在则将该键的值设置为value,相当于SET key value ,返回的是追加后字符串的总长度如:
redis > set foo hello
OK
redis > APPEND foo " world!"//此时foo中的值是 hello world!
(integer) 12

5:获取字符串长度
STRLEN key

strlen命令返回键值的长度,如果键不存在则返回0。例如:
redis > STRLEN key
(integer) 12
redis > SET key “你好”
OK
redis > strlen key
(integer) 6
前面提到字符串类型可以存储二进制数据,所以他可以存储任何编码类型的字符串。例中接收到的是使用utf-8编码的中文,由于“你”和“好”两个字的utf-8编码长度都是3,所以长度是6

6:同时获得/设置多个键值
MGET key [key ...]
MSET key value [key value ...]

MGET/MSET与GET/SET相似,不过MGET/MSET可以同时获得、设置多个键的键值。如:
redis > MSET key1 v1 key2 v2 key3 v3
OK
redis > MGET key1 key2
1). “v1”
2). “v2”

7:位操作
GETBIT key offest
SETBIT key offest value
BITCOUNT key [start] [end]
BITOP operation destkey key [key ...]

一个字节由8个二进制位组成,redis提供了4个命令可以直接对二进制位进行操作。例如,先赋值bar给foo:
redis > set foo bar
OK
bar 的3个字母“b”“a”和“r”对应的ASCII码分别为98、97和114,转换成二进制后,分别为01100010、01100001和01110010。
GETBIT命令可以获得一个字符串类型指定位置的二进制位的值(0或1),索引从0开始:
redis > GETBIT foo 0
(integer) 0
redis > GETBIT foo 6
(integer) 1
若需要获取的二进制位的索引超过了实际长度则默认位值为0
redis > GETBIT foo 100000
(integer) 0
SETBIT命令可以设置字符串类型键指定位置的二进制的值,返回值是该位置的旧值。如我们要将foo键值设置为aar,可以通过位操作将foo键的二进制位的索引第6位设为0,第七位设为1
redis > SETBIT foo 6 0
(integer) 1
redis > SETBIT foo 7 1
(integer) 0
redis > GET foo
“aar”
如果要设置的位置超过了键值的二进制长度,SETBIT命令会自动将中间的二进制位设置为0,同理设置一个不存在的键的指定二进制位的值会自动将其前面的位赋值为0:
redis > SETBIT nofoo 10 1//nofoo 前9位0 第10位1
(integer) 0
BITCOUNT命令可以获得字符串类型键中值是1的二进制位个数,例如:
redis > BITCOUNT foo
(integer) 10
可以通过参数来限制统计的字节范围,如果我们只希望统计前两个字节(即"aa"):
redis > BITCOUNT foo 0 1
(integer) 6
BITOP该命令可以对多个字符串类型键进行位运算,并将结果存储在destkey参数指定的键中。BITOP命令支持的运算操作有AND、OR、XOR和NOT。如我们可以对bar和aar进行OR运算:
redis > SET foo1 bar
OK
redis > SET foo2 aar
OK
redis >BITOP OR res foo1 foo2//将bar和aar进行或运算,并且将结果存入res
(integer) 3
redis > GET res
“car”
BITPOS在redis2.8.7中引入了BITPOS命令,可以获得指定键的第一位值是0或者1的位置,还是以“bar”这个键值为例,如果想获取键值中第一个二进制位为1的偏移量可以执行:
redis > SET foo bar
Ok
redis > BITPOS foo 1
(integer) 1
正如BITPOS的结果所示。“bar”中的第一个值为1的二进制位的偏移量为1(BITPOS索引从0开始)。
BITPOS的第二个和第三个参数就是指定查询范围(索引从0字节开始),例如我们要获取第二字节到第三个字节之间(即“a”和“r”)出现的第一个值为1的二进制的偏移量,则可以执行:
redis > BITPOS foo 1 1 2
(integer) 9
技巧
利用位操作命令可以非常紧凑的操作布尔值。比如如果网站的每个用户都有一个递增的整数ID,如果使用一个字符串类型键配合位操作来记录每个用户的性别(用户id作为索引,二进制位值1和0表示男性和女性)那么记录100w个用户的性别只需要占用100kb多的空间,而且由于GETBIT和SETBIT的时间复杂度都是O(1),所以读取二进制位置性能很高。但是使用SETBIT命令时,如果当前键的键值长度小于要设置的二进制位的偏移量时,redis会自动分配内存并将键值的当前长度到指定的偏移量之间的二进制位都设置为0,如果要分配的内存过大可能会造成服务器阻塞,所以,如果某个网站的用户ID是从100000001开始的那么直接存储会造成10多M的浪费,正确的做法是给每个用户的id减去100000000后再进行存储。

  1. 散列类型
    散列类型(hash)的键值也是一种字典结构,器存储了字段(field)和字段值的映射,单字段值只能是字符串,不支持其他数据类型,换句话说,散列类型不能嵌套其他的数据类型,一个散列类型可以包含最多2的32次方-1个字段。

    注意:除了散列类型,redis的其他数据类型同样也不支持数据类型嵌套
    散列类型适合存储对象:使用对象类别和ID构成键名,使用字段表示对象的属性,而字段值则存储属性值。例如要存储ID为2的汽车对象,可以分别使用名为color、name和price的3个字段来存储该辆汽车的颜色、名称和价格。

散列类型的命令

HSET key field value
HGET key field
HMSET key field value [field value ...]
HMGET key field [field ...]
HGETALL key

HSET 命令用来给字段赋值,而HGET命令用来获得字段的值。用法如下:
redis > HSET car price 500
(integer) 1
redis > HSET car name BMW
(integer) 1
redis > HGET car name
“BWM”

HSET命令的方便之处在与不区分插入和更新操作,这意味着修改数据时不需要事先判断字段是否存在来决定要执行的是插入操作还是更新操作。当执行插入操作是,HSET会返回 1 当执行更新操作是HSET会返回 0 。
提示:redis中每个键都属于一个明确的数据类型。如通过hset命令建立的键是散列类型,通过set命令建立的键就是字符串类型,使用一种类型的命令去操作另一种类型的命令会提示错误(并不是所有都是如此,如set就会覆盖已经存在的键而不论原来键是什么类型)

当需要同时设置多个字段的值时,可以使用HMSET命令。例如,下面两条语句:
HSET key field1 value1
HSET key filed2 value2
可以直接写成
HMSET ket field1 value1 filed2 value2
所以,相应的HMGET可以获得多个字段的值:
redis > HMGET car price name
1).500
2).BWM

如果想获得所有键中的字段和字段值,却不知道建中有哪些字段时,应该使用HGETALL命令。如:
redis > HMGETALL car
1).price
2).500
3).name
4).BWM

HEXISTS key field//判断字段是否存在
HSETNX key field value//当字段不存在时赋值
HINCRBY key field increment//给某个字段增加数值
HDEL key field [field ...]//删除字段

HEXISTS命令判断一个字段是否存在,存在返回 1 不存在返回 0 。如果键不存在也会返回0.
redis > HEXISTS car model
(integer) 0
redis > HSET car madel c200
(integer) 1
redis > HEXISTS car model
(integer) 1

HSETNX当字段不存在时赋值,如果已经存在,该命令将不执行。该操作是原子操作,不必担心竞态条件

HINCRBY可以使字段值增加指定的整数。,如果之前该键不存在,HINCRBY命令会自动建立该键并默认score字段在执行命令前值为 0 。命令的返回值是增加后的字段
redis > HINCRBY person score 60
(integer) 60

HDEL 命令可以删除一个或多个字段,返回值是被删除的字段个数:
redis > HDEL car price
(integer) 1
redis > HDEL car price
(integer) 0

HKEYS key//获得所有键
HVALS key//获得所有键中的字段值
HLEN key//获得字段数量
  1. 列表类型

    列表类型可以存储一个有序的字符串列表,常用的操作是向列表两端添加元素或者获得列表的某一个片段。

    列表类型内部是使用双向链表(double linked list)实现的,所以向列表两端添加元素的时间复杂度为O(1),获取越接近两端的元素速度就越快。这意味着即使是一个有几千万个元素的列表,获取头部和尾部的10条记录的速度是和只有20条记录的列表中获取头部和尾部的记录是一样快的。 不过使用链表的代价是通过索引访问元素比较慢。

    这种特性使得列表类型能非常快的完成关系型数据库难以应付的场景:如社交网站的新鲜事,我们关心的只是最新的10条内容,使用列表类型存储,即便过去几年存储了上千万个新鲜事,我们要获取最新的10条记录也是非常快的。

    列表类型也适合记录日志,可以保证加入新日志的速度不会受到已有日志数量的影响。

    借助列表类型,redis还可以作为队列使用。
    与散列类型键最多能容纳的字段数量相同,一个列表类型键最多能容纳2的32次方-1个元素

    1).命令

LPUSH key value [value ...]//向列表左边增加元素,返回值是添加元素后列表的总长度
RPUSH key value [value ...]//向列表右边添加元素,返回值是添加元素后列表的总长度

LPUSH 和 RPUSH 支持多个元素加入列表,例如:
redis > LPUSH members 1 2 3 4//先向左加入1,再向左加入2,以此类推
(integer) 4
redis > RPUSH members 1 2 3 4先向右加入1,再向右加入2,以此类推
(integer) 8

获得的members队列其实是:
1). 4
2). 3
3). 2
4). 1
5). 1
6). 2
7). 3
8). 4

从列表两端弹出元素
LPOP key
RPOP key 

LPOP(RPOP)命令是可以从列表左边(右边)弹出一个元素。LPOP(RPOP)命令执行两步操作:第一步,将列表左边(右边)的元素从列表中移除,第二步是返回被移除的元素值,如:
redis > LPOP members
“4”
redis > RPOP members
“4”
此时members列表中的元素:
1). 3
2). 2
3). 1
4). 1
5). 2
6). 3

通过LPUSH(RPUSH)以及LPOP(RPOP)的组合我们可以把列表当做栈或者队列。
当做栈(先进后出):
LPUSH和LPOP(RPUSH和RPOP);
当做队列(先进先出):
LPUSH和RPOP(RPUSH和LPOP)

LLEN key//获取列表中元素的个数
LRANGE key start stop//获得列表片段
LREM key count value//删除列表中指定的值

LLEN命令功能类似sql语句中的select count(*) from table_name,但是LLEN的时间复杂度为O(1),使用时redis会直接读取现成的值,而不需要向部分关系型数据库那样需要遍历以便数据表来统计条目数量。
redis > llen members
(integer) 6

LRANGE命令是列表类型最常用的命令之一,它能够获得列表中的某一片段,LRANGE命令返回索引从start到stop之间的所有元素(包含两端的元素)。redis的列表起始索引为0。
redis > lrange members 0 2//包含stop的值
1). ‘3’
2). ‘2’
3). ‘1’
同时lrange也支持负索引,-1代表右边第一个元素(-2代表右边第二个元素),例如要获取members 中的所有值:
redis > lrange members 0 -1
1). 3
2). 2
3). 1
4). 1
5). 2
6). 3
注意: 如果start的索引位置比stop的索引位置靠后,则会返回空列表;如果stop大于实际的索引范围,则会返回到列表最右边的元素。

LREM命令会删除列表中前count个值为value的元素,返回值是实际删除的元素个数。根据count值的不用,LREM命令的执行方式会略有差异。
1).当count > 0时,LREM命令会从列表左边开始删除前count个值为value的元素
2).当count < 0时,LREM命令会从列表右边开始删除前count个值为value的元素
3).当count = 0时,LREM命令会删除所有值为value的元素。
例如:
redis > lrem members 2 3//删除members 从左边开始的值为3的元素,按顺序删除2个
(integer) 2//删除了2个值为3的元素
1). “2”
2). “1”
3). “1”
4). “2”
redis > lrem members -1 1//删除members 从右边开始的值为1的元素,按顺序删除1个
(integer) 1
1). “2”
2). “1”
3). “2”
redis > lrem members 0 2//删除members中所有值为2的元素
(integer) 2//删除了两个
1). “1”

列表其他命令

LINDEX key index//获得索引的value值
LSET key index value//设置索引为index的值为value
LTRIM key start end//保留列表指定片段从start到end
LINSERT key BEFORE|AFTER pivot value//在值为pivot的元素前面或后面插入value元素
RPOPLPUSH source destination//从source队列的队尾弹出一个元素并插入destination队列的队首

如果要把列表类型当做数组来用,LINDEX 命令是必不可少的。LINDEX用来指定索引的元素,索引从0开始(从右边开始,最右边的索引为-1)。如:
redis > LINDEX members 0
“1”

LSET是另一个通过索引操作列表平的命令,他会将索引为index的元素赋值为value,例如:
redis > LSET members 0 2
OK
redis > LINDEX members 0
“2”

LTRIM命令可以删除指定索引范围之外的所有元素,其指定列表范围的方法和LRANGE命令相同。例如:member 为10 9 8 7 6 5 4 3 2 1的列表
redis > LTRIM member 0,8//保留从10 - 2的数值 ,删除了1
OK
LTRIM常和LPUSH一起使用,例如:我们只希望保留最近的100条日志,则每次加入新元素时调用一个LTRIM命令即可:
LPUSH logs $newLogs
LTRIM logs 0 99

LINSERT 会在列表中从左到右查找值为pivot的元素,然后根据第二个参数是BEFORE还是AFTER来决定将value插入到该元素的前面还是后面,如:
redis > LINSERT member AFTER 2 1//在2的后面插入元素1
(integer) 10//返回列表元素总数

RPOPLPUSH source destination 该命令会弹出source键的最右边的元素,然后插入到destination键的最左边(source和destination可以是相同的key),并返回这个元素的值,整个过程是原子的。例如:
redis > rpoplpush members member//将members的最右边的值,插入member的队首
“1”
redis > lrange members 0 -1
(empty list or set)
redis > lrange member 0 -1
1).“1”
2). “10”
3). “9”
4). “8”
5). “7”
6). “6”
7). “5”
8). “4”
9). “3”
10). “2”
11). “1”
使用rpoplpush的好处在于,在不断的使用rpoplpush命令的同时还可以不断的向列表中插入新的value,允许多个客户端同时处理队列

  1. 集合类型
    在集合中的每个元素都是不同的,且没有顺序,一个集合类型(set)键可以存储至多2的32次方-1个字符串。

集合类型和列表类型有很多相似的地方,但是也很容易区分。

集合类型列表类型
存储最多2的32次方-1个字符串存储最多2的32次方-1个字符串
无序的有序的
唯一的不唯一的

集合类型的常用操作是向集合中加入或删除元素、判断某个元素是否存在等,由于集合类型在redis内部是使用值为空的散列表(hash table)实现的,所以这些操作的时间复杂度都为O(1)。最方便的是多个集合类型之间还可以进行并集、交集和差集运算。

命令

SADD key member [member ...]//向集合中加入元素
SREM key member [member ...]//向集合中删除元素

SADD 命令向集合中增加一个或多个元素,如果键不存在则自动创建。如果要加入的元素已存在,则会跳过。返回成功加入元素的个数,如:
redis > SADD letters a
(integer) 1
redis > SADD letters a b c
(intefer) 2

SREM 命令用来从集合中删除一个或多个元素,并返回删除成功的个数,如:
redis > SREM letters c d
(integer) 1
由于d不存在 所以成功删除了c

smembers key//返回集合中所有的元素

smembers 命令会返回集合中所有的元素,例如:
redis > smembers letters
1).“a”
2).“b”
3).“abc”

sismember key member//判断是否在集合中

判断一个元素是否在集合中是一个时间复杂度为O(1)的操作,无论集合中有多少个元素,sismember命令始终可以极快的返回结果,当值存在时sismember命令返回1,当值不存在或键不存在时,sismember返回0,例如:
redis > sismember letters a
(integer) 1
redis > sismember letters asd
(integer) 0

集合间运算
SDIFF key [key ...]//差集运算
SINTER key [key ...]
SUNION key [key ...]

SDIFF 命令是用来进行多个集合间执行差集运算。集合A与集合B的差集表示为A-B,代表着属于A且不属于B的元素构成的集合 ,即A-B={x包含于A且不包含于B}。例如:
{1,2,3} - {2,3,4} = {1}
{2,3,4} - {1,2,3} = {4}
redis > sadd setA 1 2 3
(integer) 3
redis > sadd setB 2 3 4
(integer) 3
redis > SDIFF setA setB
“1”
redis > SDIFF setB setA
“4”
SDIFF从左往右开始计算,该命令支持同时传入多个键,例如:
redis > SADD setC 2 3
(integer) 2
redis > SDIFF setA setB setC
“1”
计算顺序为 先计算setA - setB 在计算结果与 setC 的差集。

SINTER命令用来对多个集合执行交集运算。集合A与集合B的交集为A∩B,代表所有即属于A有属于B的元素构成的集合,即A∩B = {x|x∈A且x∈B}。如:
{1,2,3} ∩ {2,3,4} = {2,3}
redis > sinter setA setB//同样可以传入多键值与sdiff一样
1). “2”
2). “3”

SUNION 命令用来对多个集合执行并集运算。集合A与集合B的并集表示为A∪B,代表所有属于A或属于B的元素构成的集合,即A∪B = {x|x∈A或x∈B}。如:
{1,2.3}∪{2,3,4} = {1,2,3,4}
reids > sunion setA setB//同样可以传入多键值与sdiff一样
1). “1”
2). “2”
3). “3”
4). “4”

其他命令

SCARD key//获得集合中的元素个数
SDIFFSTORE detination key [key ...]//进行差集运算并将结果存储
SINTERSTORE destination key [key ...]//进行交集运算并将结果存储
SUNIONSTORE destination key [key ...]//进行并集运算并将结果存储
SRANDMEMBER key [count]//随机获得集合中的元素
SPOP key//从集合中弹出一个元素

scard key 获得集合中元素的个数
redis > scard setA
(integer) 3

sdiffstore 命令和sdiff命令功能一样,唯一的区别就是前者不会直接返回运算结果,而是将结果存储在destination键中。如:
redis > sdiffstore setD setA setB
(integer) 1
redis > smembers setD
1). “1”

srandmember 命令用来随机从集合中获取一个元素,count值为取得多少个元素,正负数有不同的含义:
count > 0 count为正数,smember会随机从集合中获取count个不重复的元素,如果count大于整个集合的总数则返回集合
count < 0 count为负数,smember会随机从集合中获取count个元素(可能会重复)
count = 0 返回空集合
例如:
redis > srandmember setA 2
1).“1”
2).“2”
redis > srandmember setA -2
1).“1”
1).“1”
redis > srandmember setA 0
(empty list or set)

spop命令用于从集合中随机弹出一个元素。例如:
redis > spop setA
“1”
redis > smembers setA
“2”
“3”

注意:关于srandmember,该命令返回的数据并不是非常随机的,这里面涉及到一个概率的问题,概率并不是平均的 ,出现这种情况是由于集合类型采用的存储结构(散列表)造成的。散列表使用散列函数,将元素映射到不同的存储位置(桶)上,以实现O(1)的时间复杂度。
例如:
当散列表存储元素b时,使用散列函数计算出b的散列值是0,所以将b存入编号为0的桶(bucket)中,下次要查找b时就可以用同样的散列函数再次计算b的散列值并直接到相应的桶中找到b。当两个不同的元素的散列值相同时会出现冲突,redis使用拉链法来解决冲突,即将散列值冲突的元素以链表的形式存入同一个桶中,查找元素时先找到元素对应的桶,然后在从桶中找到对应的元素,使用srandmember命令时,redis会先从所有桶中随机选择一个桶,然后在该桶中所有的元素随机选择一个元素。
比如三个桶:
桶0 a c d
桶1 empty
桶2 b
从三个桶中随机选中一个非空桶,在从非空桶中所有的元素随机选择一个,这样出现b的概率就最大(因为选中桶2就只能返回b)

  1. 有序集合类型 (sorted set)
    在集合类型的基础上有序集合类型为集合中的每个元素都关联了一个分数,这使得我们不仅可以完成插入、删除和判断元素是否存在等集合类型支持的操作,还能够获得分数最高(或最低)的前N个元素、获得指定分数范围内的元素等与分数有关的操作。虽然集合中每个元素都是不同的但是他们的分数可以相同。
    有序集合类型在某些方面和列表类型有些相似:
    1).二者都是有序的
    2).二者都可以获得某一范围的元素
    但是二者有很大的区别,这使得他们的应用场景也是不同的
    1). 列表类型是通过链表实现的,获得靠近两端的数据速度极快,而元素增多后,访问中间数据的速度会慢,所以他更加适合实现如“新鲜事”或“日志”这样很少访问中间元素的应用
    2).有序集合类型是使用散列表和跳表(skip list)实现的,所以即使读取位于中间部分的数据速度也很快(时间复杂度是O(log(N)))
    3).列表中不能简单地调整某个元素的位置,但是有序集合可以(通过更改这个元素的分数)
    4).有序集合要比列表类型更耗费内存。
    有序集合算是redis5种数据类型中最高级的了

有序集合的命令

ZADD key score member [score member ...]向有序集合中加入一个元素和该元素的分数
ZSCORE key member 获得某一元素分数
ZRANGE key start stop [WITHSCORES]获得某一个集合的某一片段(从小到大)
ZREVRANGE key start stop [WITHSCORES]获得某一个集合的某一片段(从大到小)
ZRANGEBYSCORE key min max [WITHSCORE] (LIMIT offset count)//获得指定分数范围的元素(从小到大)
ZREVRANGEBYSCORE key min max [WITHSCORE] (LIMIT offset count)//获得指定分数范围的元素(从大到小)
ZINCRBY key increment member //增加某个元素的分数

zadd命令用来向有序集合中加入一个元素和该元素的分数,如果该元素已经存在则会用新的分数替换原有的分数。zadd命令返回值是新加入到集合中的元素个数(不包含之前存在的元素)

redis > zadd scoreboard 89 Tom 67 Peter 100 David
(integer) 3
可以用zadd修改原有记录
redis > zadd scoreboard 76 Peter
(integer) 0
分数不仅仅是整数,还支持双精度浮点数(但是只能是数字):
redis > zadd testboard 17E+307 a
(integer) 1
redis > zadd testboard 1.5 b
(integer) 1
resdis> zadd testboard +inf c
(integer) 1
redis > zadd testboard -inf d
(integer) 1
+(-)inf 分别表示正无穷和负无穷

zscore 命令获得某一元素的分数
redis > zscore scorebord Tom
“89”

zrange 命令会按照元素的分数从小到大的顺序返回索引从start到stop之间的所有元素(包含两端的元素)。与lrange十分相似,索引也是从0开始。(-1代表最后一个元素)

redis > zrange scoreboard 0 2
1). “Peter”
2). “Tom”
3). “David”

redis > zrange scoreboard 0 -1
1). “Peter”
2). “Tom”
3). “David”

如果需要同时获得分数可以再尾部加上withscores
1). “Tom”
2). “70”
3). “Peter”
4). “79”
5). “David”
6). “100”
zrange的时间复杂度为O(log n+m)(其中n为有序集合的基数,m为返回的元素个数)。如果两个元素的分数相同,redis会按照字典顺序(即"0"<“9”<“A”<“Z”<“a”<"z"这样的顺序)。如果是中文的话,排序取决于中文的编码方式。

zrangebyscore 命令按照元素分数从小到大顺序返回分数在min和max之间(包含min和max)的元素:
redis > zrangebysore scoreboard 79 100
1).“Peter”
2).“David”

如果希望分数范围不包含端点值,则可以再分数前加上小括号【 ( 】,例如:
redis > zrangebyscore (79 100
1).“David”

min和max还支持正负无穷(+inf和-inf)。
该命令的limit offset count 和sql的语句基本相同,获取该分数范围内的前几个元素,例如
redis > zrangebyscore 0 +inf limit 0 2//获取0到正无穷的分数之间的所有元素中的从第0个元素开始(包括第0个元素)的后两个值。
1). “Tom”
2).“Peter”

zincrby 命令可以增加(减少,incrment是一个负数)一个元素的分数,返回值是更改后的分数,如果不存在,则zincrby会先建立它的分数赋为0再执行操作。例如:
redis > zincrby scoreboard 60 Jerry
“60”

其他命令

ZCARD key//获得集合中元素的数量
ZCOUNT key min max//获得指定分数范围内的元素个数
ZREM key member [member ...]//ZREM 删除一个或多个元素
ZREMRANGEBYRANK key start stop//按照排名范围删除元素
ZREMRANGEBYSCORE key min max//按照分数范围删除元素
ZRANK key member//获得元素排名(从小到大)
ZREVRANK key member//获得元素排名(从大到小)
ZINTERSTORE destination numberkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE|SUM|MIN|MAX]//计算多个有序集合的交集
ZUNIONSTORE destination numberkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE|SUM|MIN|MAX]//计算多个有序集合的并集 

zcard key
获得集合中元素的数量
redis > zcard scoreboard
“4”

zcount 获得指定范围内元素的个数,例如:
redis > zcount key scoreboard 80 100
(integer) 1

zrem 命令的返回值是成功删除的元素数量(不包含本来就不存在的元素)
redis > zrem scoreboard Jerry
(integer) 1

zremrangebyrank 按照元素分数从小到大的顺序(即索引0表示最小值)删除在指定排名范围内的元素,并返回删除的元素数量。:例如:
redis > zrenrangebyrank scoreboard 0 1//删除索引为0和1的值
(integer) 2

zremrangebyscore 命令会删除指定范围内的所有元素,参数就min和max的特性和zrangebyscore命令中的一样。返回值是删除元元素数量。例如:
redis > zremrangebyscore scoreboard (79 100
(integer) 1

zrank命令会按照元素分数从小到大顺序获得指定的元素排名(从0开始,即分数最小的元素排名为0),例如:
redis > zrank scoreboard Peter
(integer) 2

zinterstore 命令用来计算多个有序集合的交集并将结果存储在destination键中(同样以有序集合类型存储),返回值为detination键中的元素个数。
destination键中的元素的分数是有aggregate参数决定的。
1).当参数是sum时(默认为sum),destination键中元素的分数是每个参与计算的集合中的元素分数的和。例如:
redis > zadd sortedSets1 1 a 2 b
(integer) 2
redis > zadd sortedSets2 10 a 20 b
(integer) 2
redis > zinterstore storeSetsResult 2 sortedSets1 sortedSets2
(integer) 2
redis > zrange stortedSetsResult 0 -1 withscores
“a”
“11”
“b”
“22”

2).当aggregate 是min时,destination键中元素的分数是每个参与计算的集合中该元素分数的最小值。
redis > zinterstore sortedSetsResult 2 sortedSets1 sortedSets2 aggregate min
(intger) 2
redis > zrange stortedSetsResult 0 -1 withscores
“a”
“1”
“b”
“2”

3).当aggregate 是max时,destination键中元素的分数是每个参与计算的集合中该元素分数的最大值。
redis > zinterstore sortedSetsResult 2 sortedSets1 sortedSets2 aggregate max
(intger) 2
redis > zrange stortedSetsResult 0 -1 withscores
“a”
“10”
“b”
“20”

同时该命令还可以在weghts中设置每个集合的权重,每个集合在参与计算时,元素的分数会被乘上该集合的权重。例如:
redis > zinterstore sortedSetsResult 2 sortedSets1 sortedSets2 WEIGHTS 1 0.1//sortedSets1 全部元素分数乘以1 sortedSets2 全部元素分数乘以0.1
(integer) 2
redis > zrange sortedSetsResult 0 -1 WITHSCORES
“a”
“2”
“b”
“4”

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值