Redis基本知识说明

Redis简介:

Redis是一个开源的内存中的数据结构存储系统,它可以用作:数据库、缓存和消息中间件。

数据结构类型有:String、List、Set、Hash、ZSet这5种
在这里插入图片描述

Redis默认有16个数据库
默认使用的是第0个
可以使用select 【下标】来切换数据库

127.0.0.1:6379> keys * #查看数据库所有的key
(empty array)
127.0.0.1:6379> flushdb  #清除当前库
OK

127.0.0.1:6379> flushall #清除所有库
OK

Redis是单线程的

明白Redis是很快的,官方表示,redis是基于内存操作,CPU不是redis性能瓶颈,Redis的瓶颈最有可能是机器内存的大小或者网络带宽。既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案了

Redis为什么这么快?

1、完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1);

2、数据结构简单,对数据操作也简单,Redis中的数据结构是专门进行设计的;

3、采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗

4、使用多路I/O复用模型,非阻塞IO;这里“多路”指的是多个网络连接,“复用”指的是复用同一个线程。

   多路I/O复用模型是利用 select、poll、epoll 可以同时监察多个流的 I/O 事件的能力,在空闲的时候,
   轮询那些真正发出了事件的流),并且只依次顺序的处理就绪的流,这种做法就避免了大量的无用操作

5、使用底层模型不同,它们之间底层实现方式以及与客户端之间通信的应用协议不一样,Redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求;

那么为什么Redis是单线程的?
因为Redis是基于内存的操作,CPU不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存的大小或者网络带宽。既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案了(毕竟采用多线程会有很多麻烦!)。

127.0.0.1:6379> EXPIRE name 10  #设置key的过期时间,单位是秒 实际业务可用于单点登录,例如存储一定时间的验证码
(integer) 1
127.0.0.1:6379> ttl name  # 查看key的剩余时间
(integer) 5

redis-key

String

127.0.0.1:6379> set key1 v1  #设置值
OK
127.0.0.1:6379> get key1   #获得值
"v1"
127.0.0.1:6379> keys *   #获得所有key
1) "key1"
127.0.0.1:6379> EXISTS key1    #判断某一个key是否存在
(integer) 1
127.0.0.1:6379> APPEND key1 hello   #追加字符串,如果某一个key不存在,就相当于set key
(integer) 7
127.0.0.1:6379> EXISTS key1
(integer) 1
127.0.0.1:6379> get key1
"v1hello"
127.0.0.1:6379> STRLEN key1   #获取字符串的长度
(integer) 7
127.0.0.1:6379> append key1 "hello1"  #追加字符串,如果某一个key不存在,就相当于set key
(integer) 13

## i++操作
#步长i+=
127.0.0.1:6379> set views 0  #初始浏览量为0
OK
127.0.0.1:6379> get views
"0"
127.0.0.1:6379> incr views  #自增1  浏览量为+1
(integer) 1
127.0.0.1:6379> incr views
(integer) 2
127.0.0.1:6379> get views
"2"
127.0.0.1:6379> decr views   #自减1  浏览量为-1
(integer) 1
127.0.0.1:6379> decr views
(integer) 0
127.0.0.1:6379> get views
"0"
127.0.0.1:6379> INCRBY  views 10  #可以设置步长,指定增量
(integer) 10
127.0.0.1:6379> INCRBY  views 10
(integer) 20
127.0.0.1:6379> DECRBY  views 5    #可以设置步长,指定减量
(integer) 15
127.0.0.1:6379> DECRBY views 5
(integer) 10



#截取
127.0.0.1:6379> set key1 "hello,dijia"
OK
127.0.0.1:6379> get key1
"hello,dijia"
127.0.0.1:6379> GETRANGE  key1 0 3  #截取下标0-3的字符串
"hell"
127.0.0.1:6379> GETRANGE key1 0 -1   #查看所有的字符串
"hello,dijia"

#替换
127.0.0.1:6379> set key1 hello123
OK
127.0.0.1:6379> SETRANGE key1 1 xx  替换下标为1的字符为xx
(integer) 8
127.0.0.1:6379> get key1
"hxxlo123"


#setex   (set with expire) #设置过期时间
#setnx  (set if not exist)  #不存在设置

127.0.0.1:6379> setex key3 30 "hello"  #设置key3的值为hello,30秒后过期
OK
127.0.0.1:6379> ttl key3
(integer) 23
127.0.0.1:6379> setnx mykey "redis"   #如果mykey不存在,创建mykey
(integer) 1
127.0.0.1:6379> keys *
1) "mykey"
2) "key1"
127.0.0.1:6379> ttl key3
(integer) -2
127.0.0.1:6379> setnx mykey "monggoDb"   #如果mykey存在,创建失败
(integer) 0
127.0.0.1:6379> get mykey
"redis"


#批量设置值
127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3   #
OK
127.0.0.1:6379> keys *
1) "k3"
2) "k1"
3) "k2"
127.0.0.1:6379> mget k1 k2 k3
1) "v1"
2) "v2"
3) "v3"

127.0.0.1:6379> msetnx k1 v1 k4 v4   #msetnx 是一个原子性的操作,要么一起成功要么一起失败
(integer) 0
127.0.0.1:6379> get k4
(nil)

#对象
set user:1{name:zhangsan,age:12} #设置一个user1对象  值为json字符来保存一个对象

 #这里的key是一个巧妙的设计: user:{id}:{fileid} ,如此设计在redis中完全OK
127.0.0.1:6379> mset user:1:name zhangsan user:1:age 2
OK
127.0.0.1:6379> mget user:1:name user:1:age
1) "zhangsan"
2) "2"

##########################################
getset  #先get然后再set

127.0.0.1:6379> getset db redis  #如果不存在值则返回nil
(nil)
127.0.0.1:6379> get db  
"redis"
127.0.0.1:6379> getset db mongdb     #如果存在值则获取原来的值并设置新的值
"redis"
127.0.0.1:6379> get db
"mongdb"

List

list基本的数据类型,列表
在这里插入图片描述
在redis里,我们可以把list玩成,栈,队列,阻塞队列

所有的list命令都是l开头的

##########################################
127.0.0.1:6379> lpush list one  #将一个值或者多个值插入到列表的头部(左)
(integer) 1
127.0.0.1:6379> lpush list two
(integer) 2
127.0.0.1:6379> lpush list three
(integer) 3 
127.0.0.1:6379> LRANGE  list 0 -1  #获取list中值
1) "three"
2) "two"
3) "one"
127.0.0.1:6379> LRANGE list 0 1  #通过区间获取具体的值
1) "three"
2) "two"
127.0.0.1:6379> rpush list right  #将一个值或者多个值插入到列表的尾部(右)
(integer) 4
127.0.0.1:6379> LRANGE list 0 -1
1) "three"
2) "two"
3) "one"
4) "right"

##########################################
lpop
rpop

127.0.0.1:6379> LRANGE list 0 -1
1) "three"
2) "two"
3) "one"
4) "right"
127.0.0.1:6379> lpop list  #移除列表的第一个元素
"three"
127.0.0.1:6379> rpop list  #移除列表的最后一个元素
"right"
127.0.0.1:6379> LRANGE list 0 -1
1) "two"
2) "one"
#####################################################
lindex

127.0.0.1:6379> LRANGE list 0 -1
1) "two"
2) "one"
127.0.0.1:6379> lindex list 1  #通过下标获取list中的某一个值
"one"
127.0.0.1:6379> lindex list 0
"two"

#######################################################
llen

127.0.0.1:6379> lpush list one
(integer) 1
127.0.0.1:6379> lpush list two
(integer) 2
127.0.0.1:6379> lpush list three
(integer) 3
127.0.0.1:6379> llen list  #返回列表的长度
(integer) 3

#######################################################
lrem

127.0.0.1:6379> lrem list 1 one  #移除list集合中指定个数的value,精确匹配
(integer) 1
127.0.0.1:6379> LRANGE list 0 -1
1) "three"
2) "two"
127.0.0.1:6379> lpush list three
(integer) 3
127.0.0.1:6379> lrem list 2  three
(integer) 2
127.0.0.1:6379> LRANGE list 0 -1
1) "two"
#################################################
ktrim
127.0.0.1:6379> Rpush list "hello"
(integer) 1
127.0.0.1:6379> rpush list "hello1"
(integer) 2
127.0.0.1:6379> rpush list "hello2"
(integer) 3
127.0.0.1:6379> rpush list "hello3"
(integer) 4
127.0.0.1:6379> ltrim list 1 2  #通过下标截取指定长度
OK
127.0.0.1:6379> Lrange list 0 -1
1) "hello1"
2) "hello2"
####################
#rpoplpush #移除列表的最后一个元素,并移到新的列表中

127.0.0.1:6379> Lrange list 0 -1
1) "hello1"
2) "hello2"
127.0.0.1:6379> rpoplpush list mylist  #移除列表的最后一个元素,并移到新的列表中
"hello2"
127.0.0.1:6379> lrange mylist 0 -1   #查看新列表确实存在该值
1) "hello2"
########################################
lset  将列表中指定下标的值替换为另一个,更新操作
127.0.0.1:6379> exists list  #判断这个列表是否存在,不存在则报错
(integer) 1
127.0.0.1:6379> lset list 0 item   #存在更新该下标的值
OK
127.0.0.1:6379> lrange list  0 -1  #查询更新成功
1) "item"
##############################################
linsert  将某个具体的value插入到某个元素的前面或者后面

127.0.0.1:6379> rpush list "hello"
(integer) 1
127.0.0.1:6379> rpush list "word"
(integer) 2
127.0.0.1:6379> linsert list before "word" "other"
(integer) 3
127.0.0.1:6379> lrange list 0 -1
1) "hello"
2) "other"
3) "word"
127.0.0.1:6379> linsert list after "word" "new"
(integer) 4
127.0.0.1:6379> lrange list 0 -1
1) "hello"
2) "other"
3) "word"
4) "new"

在这里插入图片描述

Set集合类型

set集合中的值是不能重复的

127.0.0.1:6379> sadd myset "hello"  #set集合合中添加值
(integer) 1
127.0.0.1:6379> sadd myset "kuangshen"
(integer) 1
127.0.0.1:6379> sadd myset "love"
(integer) 1
127.0.0.1:6379> SMEMBERS myset   #查看set集合中的值
1) "hello"
2) "love"
3) "kuangshen"
127.0.0.1:6379> SISMEMBER myset hello  #判断某一个值是不是在set集合中
(integer) 1
127.0.0.1:6379> scard myset   #获取set集合中的内容元素个数
(integer) 3
######################
srem   移除

127.0.0.1:6379> srem myset kuangshen  #移除set集合中的指定元素
(integer) 1
127.0.0.1:6379> SMEMBERS myset  #查看set集合中的值
1) "hello"
2) "love"
#################
set 无序不重复集合

127.0.0.1:6379> SRANDMEMBER myset   #随机抽选出一个元素
"hello"
127.0.0.1:6379> SRANDMEMBER myset
"hello"
127.0.0.1:6379> SRANDMEMBER myset
"hello"
127.0.0.1:6379> SRANDMEMBER myset
"love"
127.0.0.1:6379> SRANDMEMBER myset 2   #随机抽选出指定个数的元素
1) "hello" 
2) "love"

#################################
spop   随机删除set集合中的一些元素
127.0.0.1:6379> SMEMBERS myset
1) "456"
2) "hello"
3) "love"
4) "123"
127.0.0.1:6379> spop myset
"hello"
127.0.0.1:6379> spop myset
"456"
127.0.0.1:6379> SMEMBERS myset
1) "love"
2) "123"

127.0.0.1:6379> sadd myset2 "word"
(integer) 1
127.0.0.1:6379> smove myset myset2 123     #把指定set的值一定到另一个set集合
(integer) 1  
127.0.0.1:6379> SMEMBERS myset2
1) "word"
2) "123"

在这里插入图片描述

Hash

Map集合,key-map 时候是一个map集合!本质和string类型没有太大区别,还是一个简单的key-value

127.0.0.1:6379> hset myhash filed1 123   #set一个具体 key-value
(integer) 1
127.0.0.1:6379> hget myhash filed1   #获取一个字段值
"123"
127.0.0.1:6379> hmset myhash filed1 hell0 filed2 world   #set多个 key-value
OK
127.0.0.1:6379> hmget myhash filed1 filed2   #获取多个字段值
1) "hell0"
2) "world"
127.0.0.1:6379> hgetall myhash   #获取全部的数据
1) "filed1"
2) "hell0"
3) "filed2"
4) "world"
127.0.0.1:6379> hdel myhash filed1    #删除指定hash 的key字段,对应的value值也就没有了
(integer) 1 
127.0.0.1:6379> hgetall myhash
1) "filed2"
2) "world"
127.0.0.1:6379> hlen myhash  #查看hash的字段长度
(integer) 1
127.0.0.1:6379> HEXISTS myhash filed1  #判断hash中指定字段是否存在
(integer) 0
127.0.0.1:6379> HEXISTS myhash filed2
(integer) 1
127.0.0.1:6379> hkeys myhash  #只获取所有的hash key
1) "filed2"
127.0.0.1:6379> hvals myhash  #只获取所有的hash value
1) "world"
############################################
127.0.0.1:6379> hset myhash filed3 5
(integer) 1
127.0.0.1:6379> HINCRBY myhash filed3 1  #指定增量
(integer) 6
127.0.0.1:6379> HINCRBY myhash filed3 -1   #指定减量
(integer) 5
127.0.0.1:6379> Hsetnx myhash filed4 hello   #如果不存在则可以设置
(integer) 1
127.0.0.1:6379> hsetnx myhash filed4 word    #如果存在则不可以设置
(integer) 0

Zset(有序集合)

127.0.0.1:6379> zadd myset 1 one   #添加一个值
(integer) 1
127.0.0.1:6379> zadd myset 2 two
(integer) 1
127.0.0.1:6379> zadd myset 3 three
(integer) 1
127.0.0.1:6379> zrange myset 0 -1    #查看所有值
1) "one"
2) "two"
3) "three"
127.0.0.1:6379> zadd myset 4 fore 5 five  #添加多个值
(integer) 2
####################################################
排序如何实现

#添加三个用户
127.0.0.1:6379> zadd salary 500 a
(integer) 1
127.0.0.1:6379> zadd salary 800 b
(integer) 1
127.0.0.1:6379> zadd salary 1500 c
(integer) 1
#ZRANGEBYSCORE  key  min  max  语法
127.0.0.1:6379> ZRANGEBYSCORE salary -inf +inf  #显示全部的用户从小到大
1) "a"
2) "b"
3) "c"
127.0.0.1:6379> ZREVRANGE salary 0 -1  #显示全部的用户从大到小
1) "c"
2) "b"
127.0.0.1:6379> ZRANGEBYSCORE salary -inf +inf withscores  #显示全部的用户从小到大并且附带成绩
1) "a"
2) "500"
3) "b"
4) "800"
5) "c"
6) "1500"
127.0.0.1:6379> ZRANGEBYSCORE salary -inf 1000 withscores #显示工资小于1000的用户降序排序
1) "a"
2) "500"
3) "b"
4) "800"
#######################################################
127.0.0.1:6379> zrange salary 0 -1   #查看所有元素
1) "a"
2) "b"
3) "c"
127.0.0.1:6379> zrem salary a   移除有序集合中的指定元素
(integer) 1
127.0.0.1:6379> zrange salary 0 -1
1) "b"
2) "c"
#获取有序集合中的个数
127.0.0.1:6379> zcard salary
(integer) 2
########################################
127.0.0.1:6379> zadd myset 1 hello
(integer) 1
127.0.0.1:6379> zadd myset 2 world 3 baby
(integer) 2
127.0.0.1:6379> zcount myset 1 3   #获取指定区间的成员数量
(integer) 3
127.0.0.1:6379> zcount myset 1 2
(integer) 2

三种特殊数据类型

Geospatial地理位置

朋友的定位,附近的人,打车位置距离计算
可以查询一些地理位置数剧http://www.jsons.cn/lngcode/02

getadd #添加地理位置

官方文档:https://www.redis.net.cn/order/3685.html

将指定的地理空间位置(纬度、经度、名称)添加到指定的key中。这些数据将会存储到sorted set这样的目的是为了方便使用GEORADIUS或者GEORADIUSBYMEMBER命令对数据进行半径查询等操作。
#有效的经度从-180度到180度。
有效的纬度从-85.05112878度到85.05112878度。
当坐标位置超出上述指定范围时,该命令将会返回一个错误
127.0.0.1:6379>  geoadd china:city  39.90 116.40  beijin 31.23 121.47 shanghai 
(error) ERR invalid longitude,latitude pair 39.900000,116.400000
#getadd添加地理位置 
#规则 两级无法直接添加,我们一般会下载城市数据,通过java程序直接导入
127.0.0.1:6379> geoadd china:city 116.40 39.90 beijing
(integer) 1
127.0.0.1:6379> geoadd china:city 121.47 31.23 shanghai
(integer) 1
127.0.0.1:6379> geoadd china:city 106.50 29.53 chongqing
(integer) 1
127.0.0.1:6379> geoadd china:city 114.05 22.52 shenzhen
(integer) 1
127.0.0.1:6379> geoadd china:city 120.16 30.24 hangzhou 108.96 34.26 xian
(integer) 2

####################################
geopos  查看城市经纬度纬度信息
获得当前定位,一定是一个坐标值
127.0.0.1:6379> geopos china:city beijing
1) 1) "116.39999896287918091"
   2) "39.90000009167092543"
127.0.0.1:6379> geopos china:city chongqing
1) 1) "106.49999767541885376"
   2) "29.52999957900659211"

Redis GEODIST 命令 - 返回两个给定位置之间的距离

如果两个位置之间的其中一个不存在, 那么命令返回空值。
指定单位的参数 unit 必须是以下单位的其中一个:
m 表示单位为米。
km 表示单位为千米。
mi 表示单位为英里。
ft 表示单位为英尺。
如果用户没有显式地指定单位参数, 那么 GEODIST 默认使用米作为单位。

127.0.0.1:6379> geodist china:city shanghai chongqing   #返回两个给定位置之间的距离
"1447673.6920"

Redis GEORADIUS 命令 - 以给定的经纬度为中心, 找出某一半径内的元素

我附近的人(获得所有附近的人的地址定位) ,通过半径来查询

127.0.0.1:6379> GEORADIUS china:city 110 30 1000 km #以110 30经纬度为中心查找1000km内的城市
1) "chongqing"
2) "xian"
3) "shenzhen"
4) "hangzhou"
127.0.0.1:6379> GEORADIUS china:city 110 30 500 km withdist #显示到中心距离的位置
1) 1) "chongqing"
   2) "341.9374"
2) 1) "xian"
   2) "483.8340"
127.0.0.1:6379> GEORADIUS china:city 110 30 500 km withcoord  #显示他人的定位信息100km内的城市并显示到
1) 1) "chongqing"
   2) 1) "106.49999767541885376"
      2) "29.52999957900659211"
2) 1) "xian"
   2) 1) "108.96000176668167114"
      2) "34.25999964418929977"
      127.0.0.1:6379> GEORADIUS china:city 110 30 500 km withcoord count 1   #筛选指定的结果
1) 1) "chongqing"
   2) 1) "106.49999767541885376"
      2) "29.52999957900659211"
127.0.0.1:6379> GEORADIUS china:city 110 30 500 km withcoord count 2
1) 1) "chongqing"
   2) 1) "106.49999767541885376"
      2) "29.52999957900659211"
2) 1) "xian"
   2) 1) "108.96000176668167114"
      2) "34.25999964418929977"

Redis GEORADIUSBYMEMBER 命令 - 找出位于指定范围内的元素,中心点是由给定的位置元素决定

找出位于指定元素周围的其他元素

127.0.0.1:6379> GEORADIUSBYMEMBER china:city beijing 1000 km
1) "beijing"
2) "xian"

geohash 返回一个或多个位置的geohash表示

#将二维的经纬度转化为一维的字符串,如果两个字符串越接近,则表示距离越近
127.0.0.1:6379> geohash china:city beijing shanghai
1) "wx4fbxxfke0"
2) "wtw3sj5zbj0"

Geo底层的实现原理其实就是Zset,我们可以使用Zset命令来操作geo

127.0.0.1:6379> zrange china:city 0 -1   #查看地图中全部的元素
1) "chongqing"
2) "xian"
3) "shenzhen"
4) "hangzhou"
5) "shanghai"
6) "beijing"
127.0.0.1:6379> zrem china:city beijing   #移除指定的元素
(integer) 1
127.0.0.1:6379> zrange china:city 0 -1
1) "chongqing"
2) "xian"
3) "shenzhen"
4) "hangzhou"
5) "shanghai"

hyperloglog

在这里插入图片描述

**测试使用**
127.0.0.1:6379> Pfadd mykey 1 2 3 4 5 6 7 8 9 10  **创建第一组元素mykey**
(integer) 1
127.0.0.1:6379> pfcount mykey  **统计mykey元素的基数数量**
(integer) 10
127.0.0.1:6379> pfadd mykey2 a s d f g h j k l m n b v c x   **创建第二组元素mykey2**
(integer) 1
127.0.0.1:6379> pfcount mykey2   
(integer) 15
127.0.0.1:6379> PFMERGE mykey3 mykey mykey2      #合并两组mykey mykey2=》mykey3  并集
OK
127.0.0.1:6379> pfcount mykey3      #查看并集的数量
(integer) 25

如果允许容错那么一定可以使用hyperloglog

Bitmap

在这里插入图片描述

测试

在这里插入图片描述
查看总共有几天打卡

127.0.0.1:6379> bitcount sign
(integer) 3

事务

Redis事物本质:一组命令的集合!一个事务中的所有命令都会被序列化,在事务执行过程中,会按顺序执行。一次性,顺序性,排他性
redis事务没有隔离级别的概念
redis单条命令是保存原子性的,但是事务不保证原子性
所有的命令在事务中,并没有直接被执行,只有在发起执行命令的时候才被执行!exec

redis的事务:
开启事务(multi)
命令入队
执行事务 exec
127.0.0.1:6379> multi    开启事务
OK
命令入队
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> get k2
QUEUED
127.0.0.1:6379> exec    执行事务
1) OK
2) OK
3) "v2"

放弃事务  discard
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> set k3 v3
QUEUED
127.0.0.1:6379> discard   取消事务 
OK
127.0.0.1:6379> get k3   事务队列中的命令都没有被执行
(nil)

Redis订阅发布

127.0.0.1:6379> SUBSCRIBE kuangshenshuo    #订阅狂神说显示订阅成功
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "nan"
127.0.0.1:6379> PUBLISH kuangshenshuo "hello world"  #狂神说发布消息发布成功
(integer) 1
127.0.0.1:6379> publish kuangshenshuo "hello,baby"
(integer) 1

127.0.0.1:6379> SUBSCRIBE kuangshenshuo
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "kuangshenshuo"
3) (integer) 1
1) "message"    #订阅端接收到消息
2) "kuangshenshuo"
3) "hello world"
1) "message"
2) "kuangshenshuo"
3) "hello,baby"

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值