内容简介:Redis入门教程目录:通过这部分让大家对Redis的五种数据结构有初步的认识,对于Redis来说,每一种数据结构都有着自己的内部编码,而且是多种实现的,这样Redis会在合适的场景选择合适的内部编码,通过这样做的好处:
Redis入门教程目录: 【Redis入门教程目录】
数据结构和内部编码
通过这部分让大家对 Redis 的五种数据结构有初步的认识,对于Redis来说,每一种数据结构都有着自己的内部编码,而且是多种实现的,这样Redis会在合适的场景选择合适的内部编码,通过 OBJECT ENCODING [key]
可以参看指定 key
的内部编码。
这样做的好处:
a. 改进内部编码,对外的数据结构和命令没有影响,对用户提供黑箱模型。
b. 多种内部编码可在不同场景下发挥各自的优势。如: ziplist
比较节约内存,但是元素比较多的时候,性能会有所下降,此时Redis会将编码自动转换为 linkedlist
,性能会有所改善。
单线程
了解Redis的单线程架构,有助于大家对Redis的进一步学习和排解问题。
Redis处理网络请时候的求单线程可以抽象成这样,通向Redis的路只有一条,且这条路是个单车道,只容的下一辆车同时使用,而我们使用的Redis命令即为这些车辆,当我们执行多个命令的时候,只有等第一个命令执行完成了后面的命令才会执行,否则会一直处于等待状态。
Redis单线程的架构需要我们注意几点
a. 一次只运行一条命令
b. 拒绝长(慢)命令(keys、flushall、flushdb、slow lua script、mutil/exec、operate、big value)
至于为什么单线程还这么快,这里有个原因,Redis客户端的到Redis服务器的网络请求采用了 多路I/O复用模型(非阻塞I/O) ,利用select
、
poll
、
epoll
可以
同时监听多个流的I/O(客户端到服务器的网络请求)事件的能力 ,在空闲的时候,会把当前线程阻塞掉,当有一个或者多个流有
I/O
事件时,就从阻塞态中唤醒,
轮训一遍所有的流 并且依次处理就绪的流。这样就算出现有的流的
I/O
因为网络原因很慢,也不会影响别的流的
I/O
(非阻塞),因为是轮训所有的流的
I/O
。这里的“多路”指的是多个网络连接,“复用”指的是复用同一个线程。
通用命令
Redis一些通用命令,比如删除一个键、计算数据库的大小、设置键的过期时间等,这些命令有很多,这里主要介绍 7
个,完整的命令大家可以参考官方文档。
-
KEYS [pattern]
时间复杂度为 O(N) ,
N
为数据库中Key
的数量。 这个命令由于时间复杂度为O(N)所以一般生产环境不使用,如果需要遍历全部数据,可以使用Scan命令,时间复杂度为O(1)。 查找所有符合给定模式pattern
的key
,比如说:
-
KEYS *
匹配数据库中所有的key
。 -
KEYS h?llo
匹配hello
、hallo
等key
。 -
KEYS h*llo
匹配hllo
和haaaaaallo
等key
。 -
KEYS h[abe]llo
匹配hallo
、hbllo
和hello
。
返回值: 符合给定模式的key
列表。
-
DBSIZE
时间复杂度为 O(1) ,计算的时候不是扫描整个表,因为Redis有个计数器,实时更新Key总数。
查找返回当前数据库的
key
的数量。返回值:返回当前数据库的
key
的数量。代码演示:
redis> DBSIZE (integer) 5 redis> SET new_key "hello_moto" # 增加一个 key 试试 OK redis> DBSIZE (integer) 6 复制代码
-
EXISTS key
时间复杂度为 O(1) 。
检查给定
key
是否存在。返回值:若
key
存在,返回1
,不存在返回0
。 -
DEL key [key ...]
时间复杂度为 O(N) ,
N
为被删除的key
的数量,其中删除单个字符串类型的key
,时间复杂度为O(1)
;删除单个列表、集合、有序集合或哈希表类型的key
,时间复杂度为O(M)
,M
为以上数据结构内的元素数量。删除指定的一个或者多个
key
,不存在的key
会被忽略。 返回值: 被删除的key
的数量。 -
EXPIRE key seconds
时间复杂度为 O(1) 。
为给定的
key
设置生存时间,当key
过期时,它会被自动 删除 。返回值:设置成功返回
1
,当key
不存在或者设置失败的时候返回0
。 -
PERSIST key
时间复杂度为 O(1) 。
移除给定
key
的生存时间,将这个key
转换成持久的。返回值:当生存时间移除成功时,返回
1
,如果key
不存在或者没有设置生存时间,返回0
。代码演示:
redis> SET mykey "Hello" OK redis> EXPIRE mykey 10 # 为 key 设置生存时间 (integer) 1 redis> TTL mykey (integer) 10 redis> PERSIST mykey # 移除 key 的生存时间 (integer) 1 redis> TTL mykey (integer) -1 复制代码
-
TTL key
时间复杂度 O(1) 。
以秒为单位,返回给定
key
的剩余生存时间(TTL,time to live)。返回值:当
key
不存在时,返回-2
,当key
存在但是没有设置生存时间时,返回-1
,否则返回key
的剩余生存时间。代码演示:
# 不存在的 key redis> FLUSHDB OK redis> TTL key (integer) -2 # key 存在,但没有设置剩余生存时间 redis> SET key value OK redis> TTL key (integer) -1 # 有剩余生存时间的 key redis> EXPIRE key 10086 (integer) 1 redis> TTL key (integer) 10084 复制代码
五种数据结构
这里介绍Redis的五种数据结构String(字符串)、Hash(哈希)、List(列表)、Set(集合)、Zset(即Sorted Set有序集合)的结构和一些命令。
字符串
字符串是Redis中最基础的数据结构。
键值结构
字符串的值虽然是字符串但是可以保存很多种类型的数据,如:简单的字符串、JSON、XML、数字、二进制等。需要注意一点的是,Redis中字符串类型的值最大能保存512MB。
命令
-
SET key value [EX seconds] [PX milliseconds] [NX|XX] 时间复杂度 O(1) 。
将字符串值
value
关联到key
,如果key
已经持有其他值,SET
就覆写旧值,无视类型,当SET
命令对一个带有生存时间(TTL)的键进行设置之后,该键原有的TTL将被清除。可选参数:
-
EX seconds
:将键的过期时间设置为seconds
秒。 执行SET key value EX seconds
的效果等同于执行SETEX key seconds value
。 -
PX milliseconds
:将键的过期时间设置为milliseconds
毫秒。执行SET key value PX milliseconds
的效果等同于执行PSETEX key milliseconds value
。 -
NX
:只在键不存在时,才对键进行设置操作。执行SET key value NX
的效果等同于执行SETNX key value
。 -
XX
:只在键已经存在时,才对键进行设置操作。
因为 SET
命令可以通过参数来实现 SETNX
、 SETEX
以及 PSETEX
命令的效果,所以 Redis
将来的版本可能会移除并废弃 SETNX
、 SETEX
和 PSETEX
这三个命令。
返回值:在Redis 2.6.12版本以前, SET
命令总是返回 OK
。
从Redis 2.6.12版本开始, SET
命令只在设置操作成功完成时才返回 OK
;如果命令使用了 NX
或者 XX
选项, 但是因为条件没达到而造成设置操作未执行, 那么命令将返回空批量回复(NULL Bulk Reply)。 代码演示:
# 使用 EX 选项 redis> SET key-with-expire-time "hello" EX 10086 OK redis> GET key-with-expire-time "hello" redis> TTL key-with-expire-time (integer) 10069 复制代码
-
GET key 时间复杂度 O(1) 。
获取与键
key
相关联的字符串值。返回值:如果键
key
不存在,那么返回特殊值nil
;否则,返回键key
的值。如果键
key
的值并非字符串类型,那么返回一个错误,因为GET
命令只能用于字符串值。代码演示:
redis> GET db (nil) redis> SET db redis OK redis> GET db "redis" 复制代码
-
DEL key [key ...] 时间复杂度为 O(N) ,
N
为被删除的key
的数量,其中删除单个字符串类型的key
,时间复杂度为O(1)
;删除单个列表、集合、有序集合或哈希表类型的key
,时间复杂度为O(M)
,M
为以上数据结构内的元素数量。删除指定的一个或者多个
key
,不存在的key
会被忽略。 返回值: 被删除的key
的数量。代码演示:
# 同时删除多个 key redis> SET name "redis" OK redis> SET type "key-value store" OK redis> SET website "redis.com" OK redis> DEL name type website (integer) 3 复制代码
-
MSET key value [key value ...] 时间复杂度 O(N) ,其中
N
为被设置的键数量。同时为多个键设置值。如果某个给定键已经存在,那么
MSET
将使用新值去覆盖旧值,如果这不是你所希望的效果,请考虑使用MSETNX
命令,这个命令只会在所有给定键都不存在的情况下进行设置。MSET
是一个 原子性(atomic) 操作,所有给定键都会在同一时间内被设置,不会出现某些键被设置了但是另一些键没有被设置的情况。返回值:
MSET
命令总是返回OK
。代码演示:
redis> MSET date "2012.3.30" time "11:00 a.m." weather "sunny" OK redis> MGET date time weather 1) "2012.3.30" 2) "11:00 a.m." 3) "sunny" 复制代码
-
MSETNX key value [key value ...] 时间复杂度 O(N) ,其中
N
为被设置的键数量。当且仅当所有给定键都** 不存在 时,为所有给定键设置值。即使只有一个给定键已经存在,
MSETNX
命令也会拒绝执行对所有键的设置操作。MSETNX
是一个 原子性(atomic) 操作,所有给定键要么就全部都被设置,要么就全部都不设置,不可能出现第三种状态。 返回值: 当所有给定键都设置成功时,命令返回1
;如果因为某个给定键已经存在而导致设置未能成功执行,那么命令返回0
。代码演示:
redis> MSETNX rmdbs "MySQL" nosql "MongoDB" key-value-store "redis" (integer) 1 redis> MGET rmdbs nosql key-value-store 1) "MySQL" 2) "MongoDB" 3) "redis" 复制代码
-
MGET key [key ...] 时间复杂度 O(N) ,其中
N
为给定键的数量。返回给定的一个或多个字符串键的值。如果给定的字符串键里面,有某个键不存在,那么这个键的值将以特殊值
nil
表示。 返回值:MGET
命令将返回一个列表,列表中包含了所有给定键的值。代码演示:
redis> SET redis redis.com OK redis> SET mongodb mongodb.org OK redis> MGET redis mongodb 1) "redis.com" 2) "mongodb.org" redis> MGET redis mongodb mysql # 不存在的 mysql 返回 nil 1) "redis.com" 2) "mongodb.org" 3) (nil) 复制代码
-
N次GET和一次MGET对比 总所周知,Redis采用的是客户端-服务器方式,即在一次round trip中,客户端发送一条命令,服务器解析命令并执行,然后向客户端返回结果,如果执行
如果我们把N
条命令,就是N
个请求N
次执行N
个返回N
条命令都放在一个请求中,一次请求多个执行一个返回,那么就可以大大的降低网络时间的开销,这个也就是Redis的pipline -
N次SET和一次MSET对比 同7
哈希
Redis的哈希是键值对的集合,是字符串字段和字符串值之间的映射。
键值结构
Hash
数据结构即数据存储为 field
、 value
的格式存储
field
、
value
看成一对键值对结构
命令
-
HSET key field value
时间复杂度 O(1) 。
将哈希表
key
中域field
的值设置为value
,如果给定的哈希表不存在,那么一个新的哈希表将被创建并执行HSET
操作,如果域field
已存在于哈希表中,那么它的旧值将被新值value
覆盖。返回值:当
HSET
命令在哈希表中新创建field
域并成功为它设置值时,命令返回1
;如果域field
已经存在于哈希表,并且HSET
命令成功使用新值覆盖了它的旧值,那么命令返回0
。代码演示:
redis> HSET website google "www.g.cn" (integer) 1 redis> HGET website google "www.g.cn" 复制代码
-
HGET key field
时间复杂度 O(1) 。
返回哈希表中给定域的值。
返回值:
HGET
命令在默认情况下返回给定域的值,如果给定域不存在于哈希表中,又或者给定的哈希表并不存在,那么命令返回nil
。 代码演示:
redis> HSET homepage redis redis.com (integer) 1 redis> HGET homepage redis "redis.com" 复制代码
-
HGETALL key
时间复杂度 O(N) ,
N
为哈希表的大小,谨慎用。返回哈希表的所有的域和值,在返回值里,紧跟每个域(field name)之后是域的值(value),所以返回值的长度是哈希表大小的两倍。
返回值:以列表形式返回哈希表的域和域的值,若
key
不存在,返回空列表。 代码演示:
redis> HSET people jack "Jack Sparrow" (integer) 1 redis> HSET people gump "Forrest Gump" (integer) 1 redis> HGETALL people 1) "jack" # 域 2) "Jack Sparrow" # 值 3) "gump" 4) "Forrest Gump" 复制代码
-
HDEL key field [field ...]
时间复杂度 O(N) ,
N
为要删除的域的数量。删除哈希表
key
中的一个或多个指定域,不存在的域将被忽略。返回值:被成功移除的域的数量,不包括被忽略的域。
代码演示:
# 测试数据 redis> HGETALL abbr 1) "a" 2) "apple" 3) "b" 4) "banana" 5) "c" 6) "cat" 7) "d" 8) "dog" # 删除单个域 redis> HDEL abbr a (integer) 1 # 删除不存在的域 redis> HDEL abbr not-exists-field (integer) 0 # 删除多个域 redis> HDEL abbr b c (integer) 2 redis> HGETALL abbr 1) "d" 2) "dog" 复制代码
-
HMSET key field value [field value ...]
时间复杂度 O(N) ,
N
为field-value
对的数量。同时将多个
field-value
(域-值)对设置到哈希表key
中,此命令会覆盖哈希表中已存在的域,如果key
不存在,一个空哈希表被创建并执行HMSET
操作。返回值:如果命令执行成功,返回
OK
,当key
不是哈希表(hash)类型时,返回一个错误。 代码演示:
redis> HMSET website google www.google.com yahoo www.yahoo.com OK redis> HGET website google "www.google.com" redis> HGET website yahoo "www.yahoo.com" 复制代码
-
HMGET key field [field ...]
时间复杂度 O(N) ,
N
为给定域的数量。返回哈希表
key
中,一个或多个给定域的值,如果给定的域不存在于哈希表,那么返回一个nil
值,因为不存在的key
被当作一个空哈希表来处理,所以对一个不存在的key
进行HMGET
操作将返回一个只带有nil
值的表。返回值:一个包含多个给定域的关联值的表,表值的排列顺序和给定域参数的请求顺序一样。
代码演示:
redis> HMSET pet dog "doudou" cat "nounou" # 一次设置多个域 OK redis> HMGET pet dog cat fake_pet # 返回值的顺序和传入参数的顺序一样 1) "doudou" 2) "nounou" 3) (nil) # 不存在的域返回nil值 复制代码
-
N次HGET和一次HMGET对比
参考字符串的
N
次GET
和一次MGET
对比,大概相同
列表
列表用于储存多个有序的字符串,列表是一种比较灵活的数据结构,可以充当 栈 和 队列 的角色。
键值结构
列表的 value
其实是一个双向链表,可以在链表的两头插入或者删除元素
命令
-
LPUSH key value [value ...]
时间复杂度 O(1) 。
将一个或多个值
value
插入到列表key
的表头,如果有多个value
值,那么各个value
值按从左到右的顺序依次插入到表头:比如说,对空列表mylist
执行命令LPUSH mylist a b c
,列表的值将是c b a
,这等同于原子性地执行LPUSH mylist a
、LPUSH mylist b
和LPUSH mylist c
三个命令,如果key
不存在,一个空列表会被创建并执行LPUSH
操作,当key
存在但不是列表类型时,返回一个错误。返回值:执行
LPUSH
命令后,列表的长度。 代码演示:
# 加入单个元素 redis> LPUSH languages python (integer) 1 # 加入重复元素 redis> LPUSH languages python (integer) 2 redis> LRANGE languages 0 -1 # 列表允许重复元素 1) "python" 2) "python" # 加入多个元素 redis> LPUSH mylist a b c (integer) 3 redis> LRANGE mylist 0 -1 1) "c" 2) "b" 3) "a" 复制代码
-
RPUSH key value [value ...]
时间复杂度 O(1) 。
将一个或多个值
value
插入到列表key
的表尾(最右边),如果有多个value
值,那么各个value
值按从左到右的顺序依次插入到表尾:比如说,对空列表mylist
执行命令RPUSH mylist a b c
,列表的值将是c b a
,这等同于原子性地执行RPUSH mylist a
、RPUSH mylist b
和RPUSH mylist c
三个命令,如果key
不存在,一个空列表会被创建并执行RPUSH
操作,当key
存在但不是列表类型时,返回一个错误。返回值:执行
RPUSH
命令后,列表的长度。 代码演示:
# 添加单个元素 redis> RPUSH languages c (integer) 1 # 添加重复元素 redis> RPUSH languages c (integer) 2 redis> LRANGE languages 0 -1 # 列表允许重复元素 1) "c" 2) "c" # 添加多个元素 redis> RPUSH mylist a b c (integer) 3 redis> LRANGE mylist 0 -1 1) "a" 2) "b" 3) "c" 复制代码
-
LPOP key
时间复杂度 O(1) 。
移除头元素并返回列表
key
新的头元素。返回值:列表的头元素。当
key
不存在时,返回nil
。 代码演示:
# 加入单个元素 redis> LLEN course (integer) 0 redis> RPUSH course algorithm001 (integer) 1 redis> RPUSH course c++101 (integer) 2 redis> LPOP course # 移除头元素 "algorithm001" 复制代码
-
RPOP key
时间复杂度 O(1) 。
移除尾元素并返回列表
key
新的尾元素。返回值:列表的尾元素。当
key
不存在时,返回nil
。 代码演示:
redis> RPUSH mylist "one" (integer) 1 redis> RPUSH mylist "two" (integer) 2 redis> RPUSH mylist "three" (integer) 3 redis> RPOP mylist # 返回被弹出的元素 "three" redis> LRANGE mylist 0 -1 # 列表剩下的元素 1) "one" 2) "two" 复制代码
-
LINDEX key index
时间复杂度 O(N) ,
N
为到达下标index
过程中经过的元素数量。因此,对列表的头元素和尾元素执行LINDEX
命令,复杂度为O(1)。返回列表
key
中,下标为index
的元素,下标(index)参数start
和stop
都以0
为底,也就是说,以0
表示列表的第一个元素,以1
表示列表的第二个元素,以此类推,你也可以使用负数下标,以-1
表示列表的最后一个元素,-2
表示列表的倒数第二个元素,以此类推,如果key
不是列表类型,返回一个错误。返回值:列表中下标为
index
的元素。如果index
参数的值不在列表的区间范围内(out of range),返回nil
。代码演示:
redis> LPUSH mylist "World" (integer) 1 redis> LPUSH mylist "Hello" (integer) 2 redis> LINDEX mylist 0 "Hello" redis> LINDEX mylist -1 "World" redis> LINDEX mylist 3 # index不在 mylist 的区间范围内 (nil) 复制代码
-
LINSERT key BEFORE|AFTER pivot value
时间复杂度 O(N) ,
N
为寻找pivot
过程中经过的元素数量。将值
value
插入到列表key
当中,位于值pivot
之前或之后,当pivot
不存在于列表key
时,不执行任何操作,当key
不存在时,key
被视为空列表,不执行任何操作,如果key
不是列表类型,返回一个错误。返回值:如果命令执行成功,返回插入操作完成之后,列表的长度。如果没有找到
pivot
,返回-1
。如果key
不存在或为空列表,返回0
。代码演示:
redis> RPUSH mylist "Hello" (integer) 1 redis> RPUSH mylist "World" (integer) 2 redis> LINSERT mylist BEFORE "World" "There" (integer) 3 redis> LRANGE mylist 0 -1 1) "Hello" 2) "There" 3) "World" # 对一个非空列表插入,查找一个不存在的 pivot redis> LINSERT mylist BEFORE "go" "let's" (integer) -1 # 失败 # 对一个空列表执行 LINSERT 命令 redis> EXISTS fake_list (integer) 0 redis> LINSERT fake_list BEFORE "nono" "gogogog" (integer) 0 # 失败 复制代码
集合
Redis的 Set
是 String
类型的无序集合,这里的集合也就是我们小学都接触到的集合,可以求交集、并集、差集等。集合成员是唯一的,这就意味着集合中不能出现重复的数据。集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。
键值结构
左边为 key
,是字符串类型。右边为 value
,可以将一些字符串进行一些组合,是集合类型。Redis中的集合类型还支持集合之间的操作,这与Redis中的其他数据结构是不同的,Redis可以对两个集合进行操作,取两个集合的交集,并集,差集以及对称差集等。
命令
-
SADD key member [member …]
时间复杂度 O(N) ,
N
为被添加的元素的数量。将一个或多个
member
元素加入到集合key
当中,已经存在于集合的member
元素将被忽略,假如key
不存在,则创建一个只包含member
元素作成员的集合,当key
不是集合类型时,返回一个错误。返回值:被添加到集合中的新元素的数量,不包括被忽略的元素。
代码演示:
# 添加单个元素 redis> SADD bbs "discuz.net" (integer) 1 # 添加重复元素 redis> SADD bbs "discuz.net" (integer) 0 # 添加多个元素 redis> SADD bbs "tianya.cn" "groups.google.com" (integer) 2 redis> SMEMBERS bbs 1) "discuz.net" 2) "groups.google.com" 3) "tianya.cn" 复制代码
-
SPOP key [count]
时间复杂度 O(1) 。
随机移除
count
个元素并返回被移除的元素。返回值:被移除的随机元素。当
key
不存在或key
是空集时,返回nil
。代码演示:
redis> SMEMBERS db 1) "MySQL" 2) "MongoDB" 3) "Redis" redis> SPOP db "Redis" redis> SMEMBERS db 1) "MySQL" 2) "MongoDB" redis> SPOP db "MySQL" redis> SMEMBERS db 1) "MongoDB" 复制代码
-
SREM key member [member …]
时间复杂度 O(N) ,
N
为给定member
元素的个数。移除集合
key
中的一个或多个member
元素,不存在的member
元素会被忽略,当key
不是集合类型,返回一个错误。返回值:被成功移除的元素的个数,不包括被忽略的元素。
代码演示:
# 测试数据 redis> SMEMBERS languages 1) "c" 2) "lisp" 3) "python" 4) "ruby" # 移除单个元素 redis> SREM languages ruby (integer) 1 # 移除不存在元素 redis> SREM languages non-exists-language (integer) 0 # 移除多个元素 redis> SREM languages lisp python c (integer) 3 redis> SMEMBERS languages (empty list or set) 复制代码
-
SMEMBERS key
时间复杂度 O(N) ,
N
为集合的基数。返回集合
key
中的所有成员,不存在的key
被视为空集合。返回值:集合中的所有成员。
代码演示:
# key 不存在或集合为空 redis> EXISTS not_exists_key (integer) 0 redis> SMEMBERS not_exists_key (empty list or set) # 非空集合 redis> SADD language Ruby Python Clojure (integer) 3 redis> SMEMBERS language 1) "Python" 2) "Ruby" 3) "Clojure" 复制代码
有序集合
Redis有序集合和集合一样也是 String
类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个 double
类型的分数。Redis正是通过分数来为集合中的成员进行从小到大的排序。有序集合的成员是唯一的,但分数(score)却可以重复。集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。
键值结构
有序集合的 value
包括 score
和 value
两部分,其中 score
表示分值用来 排序 的
命令
-
ZADD key [NX|XX] [CH] [INCR] score member [score member …]
时间复杂度 O(M*log(N)) ,
N
是有序集的基数,M
为成功添加的新成员的数量。将一个或多个
member
元素及其score
值加入到有序集key
当中。如果某个member
已经是有序集的成员,那么更新这个member
的score
值,并通过重新插入这个member
元素,来保证该member
在正确的位置上。score
值可以是整数值或双精度浮点数。如果key
不存在,则创建一个空的有序集并执行ZADD
操作。当key
存在但不是有序集类型时,返回一个错误。Redis 3.0.2 为
ZADD
命令添加了NX
、XX
、CH
、INCR
四个选项:
-
NX
:member
必须不存在,才可以设置成功,用于添加。 -
XX
:member
必须存在,才可以设置成功,用于更新。 -
CH
:返回此次操作后,有序集合元素和分数发生变化的个数。 -
INCR
:对score
做增加,相当于ZINCRBY
。 返回值: 被成功添加的新成员的数量,不包括那些被更新的、已经存在的成员。
代码演示:
redis> ZADD ztest 100 java 99 python 80 go 120 kotlin (integer) 4 # 查看有序集合内所有元素并且按分数排序 coderknock> ZRANGE ztest 0 -1 WITHSCORES 1) "go" 2) "80" 3) "python" 4) "99" 5) "java" 6) "100" 7) "kotlin" 8) "120" # 选项填写在 key 后面,位置不能错误 redis> ZADD ztest 100 java 99 python 80 go 120 kotlin CH (error) ERR syntax error redis> ZADD CH ztest 100 java 99 python 80 go 120 kotlin (error) ERR syntax error # 下面两个语句进行了对比,如果不加 CH 显示的数量不包括更新和已经存在的。 redis> ZADD ztest CH 100 java 99 python 80 go 121 kotlin (integer) 1 redis> ZADD ztest 100 java 99 python 80 go 120 kotlin (integer) 0 复制代码
-
ZREM key member [member …]
时间复杂度 O(M*log(N)) ,
N
是有序集的基数,M
为成功移除的成员的数量。移除有序集
key
中的一个或多个成员,不存在的成员将被忽略,当key
存在但不是有序集类型时,返回一个错误。返回值:被成功移除的成员的数量,不包括被忽略的成员。
代码演示:
# 测试数据 redis> ZRANGE page_rank 0 -1 WITHSCORES 1) "bing.com" 2) "8" 3) "baidu.com" 4) "9" 5) "google.com" 6) "10" # 移除单个元素 redis> ZREM page_rank google.com (integer) 1 redis> ZRANGE page_rank 0 -1 WITHSCORES 1) "bing.com" 2) "8" 3) "baidu.com" 4) "9" # 移除多个元素 redis> ZREM page_rank baidu.com bing.com (integer) 2 redis> ZRANGE page_rank 0 -1 WITHSCORES (empty list or set) # 移除不存在元素 redis> ZREM page_rank non-exists-element (integer) 0 复制代码
以上所述就是小编给大家介绍的《第二章 Redis API的使用 单线程介绍》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
perl进阶
Randal L.Schwartz、brian d.foy、Tom Phoenix / 韩雷 / 人民邮电出版社 / 2015-10-1 / 69
本书是Learning Perl一书的进阶。学完本书之后,您可以使用Perl语言的特性编写从简单脚本到大型程序在内的所有程序,正是Perl语言的这些特性使其成为通用的编程语言。本书为读者深入介绍了模块、复杂的数据结构以及面向对象编程等知识。 本书每章的篇幅都短小精悍,读者可以在一到两个小时内读完,每章末尾的练习有助于您巩固在本章所学的知识。如果您已掌握了Learning Perl中的内容并渴......一起来看看 《perl进阶》 这本书的介绍吧!