内容简介: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的使用 单线程介绍》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
The Filter Bubble
Eli Pariser / Penguin Press / 2011-5-12 / GBP 16.45
In December 2009, Google began customizing its search results for each user. Instead of giving you the most broadly popular result, Google now tries to predict what you are most likely to click on. Ac......一起来看看 《The Filter Bubble》 这本书的介绍吧!