redis数据类型及其操作命令

1、redis简介

  redis是一个开源的,基于内存的数据结构存储服务器,可以用作数据库,缓存和消息代理。由于redis是基于内存的因此它的速度非常快。并且redis是以key-value存储的,因此它也是一种NoSQL数据库。redis与其他很多产品相比有很多特性,
1、Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用;
2、Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储;
3、Redis支持数据的备份,即master-slave模式的数据备份;
因此redis有丰富的功能,可以用作缓存,实现发布/订阅系统,数据持久化,定时器和计数器等等,并且它支持简单的事务,主从复制读写分离等等。

2、redis的安装与启动

  redis一般安装在linux环境下,官方不建议安装在windows平台,但是也可以安装。我们介绍一下在linux环境下的安装。
1、下载redis的源码的压缩文件,放到你需要的目录下
2、cd 到此目录下,并解压文件:tar -zxvf redis-5.0.5.tar.gz
3、解压完成后,cd进入解压出来的文件录下
4、执行执行make && make install命令编译安装
  接下来启动redis,直接输入redis-server即可,会默认指定redis安装目录下配置文件,也可以根据自己的需求指定其他的配置文件只需要执行redis-server ****.config命令即可。执行命令后redis的服务就开启了,接下来使用客户端连接就行了,只需输入redis-cli就可以使用默认的客户端来连接。redis启动后就在默认的6379端口开启服务。默认16个数据库,默认使用0号数据库,可以通过select [index]指定切换的数据库。这里有三个常用的命令,dbsize列出当期那数据库中的key的数量;flushdb用于清除当前数据库;flushall用于清除所有数据库。

3、数据类型

  redis拥有五大数据类型:分别为String(字符串),List(列表),Hash(哈希),Set(集合),Zset(有序集合)。接下来我们分别来介绍这几种数据类型及相关命令。

  • String类型

  String是redis最基本的数据类型,它可以存储任何形式的字符串,包括二进制的数据,字符串类型的键允许存储的数据最大容量是512MB。字符串是其他几种数据类型的基础,其他数据类型和字符串类型的差别从某种角度上来讲只是组织字符串的形式不同,例如List类型是以列表的形式来组织字符串,Set类型以集合的形式来组织字符串。我们来看看它相关的命令:

  • set key value [ex seconds] [px milliseconds]

将字符串值 value 关联到 key 。
如果 key 已经持有其他值, SET 就覆写旧值, 无视类型。
对于某个原本带有生存时间(TTL)的键来说, 当 SET 命令成功在这个键上执行时, 这个键原有的 TTL 将被清除。

示例:

// 对不存在的键进行设置
redis> SET key "value"
OK
redis> GET key
"value"
// 对已存在的键进行设置
redis 127.0.0.1:6379> SET key "new-value"
OK
redis 127.0.0.1:6379> GET key
"new-value"
  • get key

如果键 key 不存在, 那么返回特殊值 nil ; 否则, 返回键 key 的值。
如果键 key 的值并非字符串类型, 那么返回一个错误, 因为 get命令只能用于字符串值。

示例

// 对不存在的 key 或字符串类型 key 进行 get
redis> GET db
(nil)
redis> SET db redis
OK
redis> GET db
"redis"
  • strlen key

返回键 key 储存的字符串值的长度。
当键 key 不存在时, 命令返回 0 。
当 key 储存的不是字符串值时, 返回一个错误。

示例

redis> set mykey "Hello world"
OK
redis> strlen mykey
(integer) 11
  • append key value

如果键 key 已经存在并且它的值是一个字符串, append 命令将把 value 追加到键 key 现有值的末尾。
如果 key 不存在, append 就简单地将键 key 的值设为 value , 就像执行 set key value 一样。
追加 value 之后,返回 键 key 的值的长度。

示例

// 对不存在的keyappend
redis> exists myphone               
(integer) 0
redis> append myphone "nokia"      
(integer) 5     

// 对存在的keyappend
redis> APPEND myphone " - 1110"     
(integer) 12
redis> GET myphone
"nokia - 1110"                    
  • SETRANGE key offset value

从偏移量 offset 开始, 用 value 参数覆写(overwrite)键 key 储存的字符串值。
不存在的键 key 当作空白字符串处理。
SETRANGE 命令会确保字符串足够长以便将 value 设置到指定的偏移量上, 如果键 key 原来储存的字符串长度比偏移量小(比如字符串只有 5 个字符长,但你设置的 offset 是 10 ), 那么原字符和偏移量之间的空白将用零字节(zerobytes, “\x00” )进行填充。
返回修改之后, 字符串值的长度。

示例

// 对非空串执行
redis> SET greeting "hello world"
OK
redis> SETRANGE greeting 6 "Redis"
(integer) 11
redis> GET greeting
"hello Redis"
// 对空串或不存在的键执行
redis> EXISTS empty_string
(integer) 0
redis> SETRANGE empty_string 5 "Redis!"   // 对不存在的 key 使用 SETRANGE
(integer) 11
redis> GET empty_string                   // 空白处被"\x00"填充
"\x00\x00\x00\x00\x00Redis!"
  • GETRANGE key start end

返回键 key 储存的字符串值的指定部分, 字符串的截取范围由 start 和 end 两个偏移量决定 (包括 start 和 end 在内)。
负数偏移量表示从字符串的末尾开始计数, -1 表示最后一个字符, -2 表示倒数第二个字符, 以此类推。
示例

redis> SET greeting "hello, my friend"
OK
redis> GETRANGE greeting 0 -1         # 从第一个到最后一个
"hello, my friend"
  • INCR key

为键 key 储存的数字值加上一。
如果键 key 不存在, 那么它的值会先被初始化为 0 , 然后再执行 INCR 命令。
如果键 key 储存的值不能被解释为数字, 那么 INCR 命令将返回一个错误。

示例

redis> SET page_view 20
OK

redis> INCR page_view
(integer) 21

redis> GET page_view    # 数字值在 Redis 中以字符串的形式保存
"21"
  • INCRBY key increment

为键 key 储存的数字值加上增量 increment 。
如果键 key 不存在, 那么键 key 的值会先被初始化为 0 , 然后再执行 INCRBY 命令。
如果键 key 储存的值不能被解释为数字, 那么 INCRBY 命令将返回一个错误。

示例

redis> SET rank 50
OK

redis> INCRBY rank 20
(integer) 70

redis> GET rank
"70"
  • INCRBYFLOAT key increment

为键 key 储存的值加上浮点数增量 increment 。
示例

redis> GET decimal
"3.0"

redis> INCRBYFLOAT decimal 2.56
"5.56"

redis> GET decimal
"5.56"
  • DECR key

  • DECRBY key decrement

与增相反

  • MSET key value [key value …]

同时为多个键设置值。
如果某个给定键已经存在, 那么 MSET 将使用新值去覆盖旧值, 如果这不是你所希望的效果, 请考虑使用 MSETNX 命令, 这个命令只会在所有给定键都不存在的情况下进行设置。
MSET 是一个原子性(atomic)操作, 所有给定键都会在同一时间内被设置, 不会出现某些键被设置了但是另一些键没有被设置的情况。

示例

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"
  • MGET key [key …]

返回给定的一个或多个字符串键的值。
如果给定的字符串键里面, 有某个键不存在, 那么这个键的值将以特殊值 nil 表示。
返回一个列表, 列表中包含了所有给定键的值。

示例

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)
  • List类型

  List类型可以存储一个有序的字符串列表,常用的操作就是向列表两端添加元素,或者获取列表中某一个片段。列表类型底层使用双向链表(double linked list)实现的,所以向列表两端添加或删除元素的速度非常快,越是接近两端的元素就越快,但是,也有弊端,就是通过索引访问元素的速度比较慢。列表中的元素是有序的,可以通过索引下标来获取某个元素或者某个范围内的元素列表,此外列表中的元素是可以重复的。我们来看看它的相关命令

  • LPUSH key value [value …]

将一个或多个值 value 插入到列表 key 的表头
如果有多个 value 值,那么各个 value 值按从左到右的顺序依次插入到表头: 比如说,对空列表 mylist 执行命令 LPUSH mylist a b c ,列表的值将是 c b a ,这等同于原子性地执行 LPUSH mylist a 、 LPUSH mylist b 和 LPUSH mylist c 三个命令。

示例

# 加入单个元素

redis> LPUSH languages python
(integer) 1
# 加入多个元素

redis> LPUSH mylist a b c
(integer) 3

redis> LRANGE mylist 0 -1
1) "c"
2) "b"
3) "a"
  • RPUSH key value [value …]

将一个或多个值 value 插入到列表 key 的表尾(最右边)。
如果有多个 value 值,那么各个 value 值按从左到右的顺序依次插入到表尾:比如对一个空列表 mylist 执行 RPUSH mylist a b c ,得出的结果列表为 a b c ,等同于执行命令 RPUSH mylist a 、 RPUSH mylist b 、 RPUSH mylist c 。
如果 key 不存在,一个空列表会被创建并执行 RPUSH 操作。
当 key 存在但不是列表类型时,返回一个错误。

示例

# 添加单个元素

redis> RPUSH languages c
(integer) 1
# 添加多个元素

redis> RPUSH mylist a b c
(integer) 3

redis> LRANGE mylist 0 -1
1) "a"
2) "b"
3) "c"
  • LPOP key

移除并返回列表 key 的头元素。
示例

redis> LLEN course
(integer) 0

redis> RPUSH course algorithm001
(integer) 1

redis> RPUSH course c++101
(integer) 2

redis> LPOP course  # 移除头元素
"algorithm001"
  • RPOP key

移除并返回列表 key 的尾元素。
示例

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"
  • RPOPLPUSH source destination

将列表 source 中的最后一个元素(尾元素)弹出,并返回给客户端。
将 source 弹出的元素插入到列表 destination ,作为 destination 列表的的头元素。

示例

# source 和 destination 不同

redis> LRANGE alpha 0 -1         # 查看所有元素
1) "a"
2) "b"
3) "c"
4) "d"

redis> RPOPLPUSH alpha reciver   # 执行一次 RPOPLPUSH 看看
"d"

redis> LRANGE alpha 0 -1
1) "a"
2) "b"
3) "c"

redis> LRANGE reciver 0 -1
1) "d"
  • LREM key count value

根据参数 count 的值,移除列表中与参数 value 相等的元素。
count > 0 : 从表头开始向表尾搜索,移除与 value 相等的元素,数量为 count 。
count < 0 : 从表尾开始向表头搜索,移除与 value 相等的元素,数量为 count 的绝对值。
count = 0 : 移除表中所有与 value 相等的值。

示例

redis> LPUSH greet "morning"
(integer) 1
redis> LPUSH greet "hello"
(integer) 2
redis> LPUSH greet "morning"
(integer) 3
redis> LPUSH greet "hello"
(integer) 4
redis> LPUSH greet "morning"
(integer) 5
redis> LREM greet 2 morning     # 移除从表头到表尾,最先发现的两个 morning
(integer) 2                     # 两个元素被移除

  • LLEN key

返回列表 key 的长度。
如果 key 不存在,则 key 被解释为一个空列表,返回 0 .
如果 key 不是列表类型,返回一个错误。

示例

# 非空列表

redis> LPUSH job "cook food"
(integer) 1

redis> LPUSH job "have lunch"
(integer) 2

redis> LLEN job
(integer) 2
  • LINDEX key index

返回列表 key 中,下标为 index 的元素。
示例

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)
  • LSET key index value

将列表 key 下标为 index 的元素的值设置为 value 。
示例

# 对非空列表进行 LSET

redis> LPUSH job "cook food"
(integer) 1

redis> LRANGE job 0 0
1) "cook food"

redis> LSET job 0 "play game"
OK

redis> LRANGE job  0 0
1) "play game"

  • LRANGE key start stop

返回列表 key 中指定区间内的元素,区间以偏移量 start 和 stop 指定。
示例

redis> RPUSH fp-language lisp
(integer) 1

redis> LRANGE fp-language 0 0
1) "lisp"

redis> RPUSH fp-language scheme
(integer) 2

redis> LRANGE fp-language 0 1
1) "lisp"
2) "scheme"
  • Set类型

  集合类型和List类型相似但也有不同之处,它们都是都字符串的一种组织形式,但是Set类型不允许元素重复,也就是说它保证了集合中元素的唯一性。一个集合类型可以存储的键的数量为2^32 - 1,在底层集合使用了hash table实现,只不过它的值为空。因此它的查找时间复杂度为O(1)。我们来看看它的常用命令

  • SADD key member [member …]

将一个或多个 member 元素加入到集合 key 当中,已经存在于集合的 member 元素将被忽略。
假如 key 不存在,则创建一个只包含 member 元素作成员的集合。

示例

# 添加单个元素

redis> SADD bbs "discuz.net"
(integer) 1
# 添加多个元素

redis> SADD bbs "tianya.cn" "groups.google.com"
(integer) 2

redis> SMEMBERS bbs
1) "discuz.net"
2) "groups.google.com"
3) "tianya.cn"
  • SISMEMBER key member

判断 member 元素是否集合 key 的成员。

redis> SMEMBERS joe's_movies
1) "hi, lady"
2) "Fast Five"
3) "2012"

redis> SISMEMBER joe's_movies "bet man"
(integer) 0

redis> SISMEMBER joe's_movies "Fast Five"
(integer) 1
  • SREM key member [member …]

移除集合 key 中的一个或多个 member 元素,不存在的 member 元素会被忽略。

# 测试数据

redis> SMEMBERS languages
1) "c"
2) "lisp"
3) "python"
4) "ruby"

# 移除单个元素
redis> SREM languages ruby
(integer) 1
  • SMOVE source destination member

将 member 元素从 source 集合移动到 destination 集合。
SMOVE 是原子性操作。

redis> SMEMBERS songs
1) "Billie Jean"
2) "Believe Me"

redis> SMEMBERS my_songs
(empty list or set)

redis> SMOVE songs my_songs "Believe Me"
(integer) 1

redis> SMEMBERS songs
1) "Billie Jean"

redis> SMEMBERS my_songs
1) "Believe Me"
  • SCARD key

返回集合 key 的基数(集合中元素的数量)。

redis> SADD tool pc printer phone
(integer) 3

redis> SCARD tool   # 非空集合
(integer) 3

  • SMEMBERS key

返回集合 key 中的所有成员。

  • SINTER key [key …]

返回一个集合的全部成员,该集合是所有给定集合的交集。
不存在的 key 被视为空集。
当给定集合当中有一个空集时,结果也为空集(根据集合运算定律)。

  • SINTERSTORE destination key [key …]

这个命令类似于 SINTER key [key …] 命令,但它将结果保存到 destination 集合,而不是简单地返回结果集。
如果 destination 集合已经存在,则将其覆盖。

  • SUNION key [key …]

返回一个集合的全部成员,该集合是所有给定集合的并集。

  • SDIFF key [key …]

返回一个集合的全部成员,该集合是所有给定集合之间的差集。

  • Zset类型

  有序集合与集合的不同之处就在于有序二字,有序集合在集合的基础之上为每一个元素都关联了一个分数,这样不仅可以完成集合的基本操作,还可以获得分数最高或最低的前N个元素、获得指定分数范围内的元素等与分数有关的操作,虽然集合中的元素是不同的但是分数却可以相同。从有序集合的特性来看,它和List类型很相似,确实它们都是有序的,都可以获取某个范围内的元素。但是它们也有很大的区别,因此在使用场景上有很大的不同。
其一,List类型的底层是使用链表来实现的,链表的特点是在获取两端的元素较快,但是当链表的元素数量增加的时候,获取中间的元素就变得比较慢了,因此它的使用场景是如同“新鲜事”或“日志”这种很少访问中间元素的行为。
其二,SortedSet是使用哈希表和跳跃表来实现的,因此即使访问中间元素也能做到O(logn)的时间复杂度。
其三,列表中不能简单地调整某个元素的位置,但有序集合可以做到,通过更改这个元素的分数
其四,有序集合比列表更耗费内存

  • ZADD key score member [[score member] [score member] …]

将一个或多个 member 元素及其 score 值加入到有序集 key 当中。
如果某个 member 已经是有序集的成员,那么更新这个 member 的 score 值,并通过重新插入这个 member 元素,来保证该 member 在正确的位置上。

# 添加单个元素

redis> ZADD page_rank 10 google.com
(integer) 1


# 添加多个元素

redis> ZADD page_rank 9 baidu.com 8 bing.com
(integer) 2

redis> ZRANGE page_rank 0 -1 WITHSCORES
1) "bing.com"
2) "8"
3) "baidu.com"
4) "9"
5) "google.com"
6) "10"
# 添加已存在元素,但是改变 score 值

redis> ZADD page_rank 6 bing.com
(integer) 0

redis> ZRANGE page_rank 0 -1 WITHSCORES  # bing.com 元素的 score 值被改变
1) "bing.com"
2) "6"
3) "baidu.com"
4) "9"
5) "google.com"
6) "10"
  • ZSCORE key member

返回有序集 key 中,成员 member 的 score 值。

redis> ZRANGE salary 0 -1 WITHSCORES    # 测试数据
1) "tom"
2) "2000"
3) "peter"
4) "3500"
5) "jack"
6) "5000"

redis> ZSCORE salary peter              # 注意返回值是字符串
"3500"
  • ZINCRBY key increment member

为有序集 key 的成员 member 的 score 值加上增量 increment 。
可以通过传递一个负数值 increment ,让 score 减去相应的值,比如 ZINCRBY key -5 member ,就是让 member 的 score 值减去 5 。

redis> ZSCORE salary tom
"2000"

redis> ZINCRBY salary 2000 tom   # tom 加薪啦!
"4000"
  • ZCOUNT key min max

返回有序集 key 中, score 值在 min 和 max 之间(默认包括 score 值等于 min 或 max )的成员的数量。

redis> ZRANGE salary 0 -1 WITHSCORES    # 测试数据
1) "jack"
2) "2000"
3) "peter"
4) "3500"
5) "tom"
6) "5000"

redis> ZCOUNT salary 2000 5000          # 计算薪水在 2000-5000 之间的人数
(integer) 3

redis> ZCOUNT salary 3000 5000          # 计算薪水在 3000-5000 之间的人数
(integer) 2
  • ZRANGE key start stop [WITHSCORES]

返回有序集 key 中,指定区间内的成员。
其中成员的位置按 score 值递增(从小到大)来排序。
可以通过使用 WITHSCORES 选项,来让成员和它的 score 值一并返回,返回列表以 value1,score1, …, valueN,scoreN 的格式表示。

redis > ZRANGE salary 0 -1 WITHSCORES             # 显示整个有序集成员
1) "jack"
2) "3500"
3) "tom"
4) "5000"
5) "boss"
6) "10086"

  • ZRANK key member

返回有序集 key 中成员 member 的排名。其中有序集成员按 score 值递增(从小到大)顺序排列。
排名以 0 为底,也就是说, score 值最小的成员排名为 0 。

redis> ZRANGE salary 0 -1 WITHSCORES        # 显示所有成员及其 score 值
1) "peter"
2) "3500"
3) "tom"
4) "4000"
5) "jack"
6) "5000"

redis> ZRANK salary tom                     # 显示 tom 的薪水排名,第二
(integer) 1
  • ZREM key member [member …]

移除有序集 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)
  • Hash类型

  redis是采用key-value形式来存储数据的,而Hash类型也是采用key-value形式来存储的,值得注意的是Hash类型的value值只能是String类型,而不能是其他类型,也就是说redis的数据类型是不支持嵌套的。不仅Hash类型不支持嵌套,redis的其他类型也不支持嵌套。

  • HSET hash field value

将哈希表 hash 中域 field 的值设置为 value 。
如果给定的哈希表并不存在, 那么一个新的哈希表将被创建并执行 HSET 操作。
当 HSET 命令在哈希表中新创建 field 域并成功为它设置值时, 命令返回 1 ; 如果域 field 已经存在于哈希表, 并且 HSET 命令成功使用新值覆盖了它的旧值, 那么命令返回 0 。

redis> HSET website google "www.g.cn"
(integer) 1

redis> HGET website google
"www.g.cn"
  • HSETNX hash field value

当且仅当域 field 尚未存在于哈希表的情况下, 将它的值设置为 value 。
如果给定域已经存在于哈希表当中, 那么命令将放弃执行设置操作。
HSETNX 命令在设置成功时返回 1 , 在给定域已经存在而放弃执行设置操作时返回 0 。

redis> HSETNX database key-value-store Redis
(integer) 1

redis> HGET database key-value-store
"Redis"
  • HGET hash field

返回哈希表中给定域的值。

  • HEXISTS hash field

检查给定域 field 是否存在于哈希表 hash 当中。
HEXISTS 命令在给定域存在时返回 1 , 在给定域不存在时返回 0 。

  • HDEL

删除哈希表 key 中的一个或多个指定域,不存在的域将被忽略。

redis> HGETALL abbr
1) "a"
2) "apple"
3) "b"
4) "banana"
5) "c"
6) "cat"
7) "d"
8) "dog"

redis> HDEL abbr b c
(integer) 2

  • HLEN key

返回哈希表 key 中域的数量。

redis> HSET db redis redis.com
(integer) 1

redis> HSET db mysql mysql.com
(integer) 1

redis> HLEN db
(integer) 2

redis> HSET db mongodb mongodb.org
(integer) 1

redis> HLEN db
(integer) 3
  • HSTRLEN key field

返回哈希表 key 中, 与给定域 field 相关联的值的字符串长度(string length)。
如果给定的键或者域不存在, 那么命令返回 0 。

redis> HMSET myhash f1 "HelloWorld" f2 "99" f3 "-256"
OK

redis> HSTRLEN myhash f1
(integer) 10

redis> HSTRLEN myhash f2
(integer) 2

redis> HSTRLEN myhash f3
(integer) 4
  • HINCRBY key field increment

为哈希表 key 中的域 field 的值加上增量 increment 。
增量也可以为负数,相当于对给定域进行减法操作。
对一个储存字符串值的域 field 执行 HINCRBY 命令将造成一个错误。

  • HMSET key field value [field value …]

同时将多个 field-value (域-值)对设置到哈希表 key 中。
此命令会覆盖哈希表中已存在的域。
如果 key 不存在,一个空哈希表被创建并执行 HMSET 操作。

  • HKEYS key

返回哈希表 key 中的所有域。

# 哈希表非空

redis> HMSET website google www.google.com yahoo www.yahoo.com
OK

redis> HKEYS website
1) "google"
2) "yahoo"
  • HGETALL

返回哈希表 key 中,所有的域和值。
在返回值里,紧跟每个域名(field name)之后是域的值(value),所以返回值的长度是哈希表大小的两倍。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值