KingbsaeES数据库分区表的详细用法


数据库版本:KingbaseES V008R006C008B0014


简介

    分区表是一种将大型数据库表拆分为更小、更可管理的部分的技术。它通过将表数据分散存储到多个物理存储单元中,可以提高查询和数据维护的性能,并优化对大型数据集的处理。本篇文章以kingbase为例介绍分区表的用法。

        

文章目录如下

1. 基本语法

1.1. 语法一

1.1.1. 一级分区

1.1.2. 二级分区

1.2. 语法二

1.2.1. 一级分区

1.2.2. 二级分区

2. 分区类型

2.1. 范围分区

2.1.1. 按金额范围分区

2.1.2. 按日期分区

2.1.3. 自动创建日期分区

2.1.4. 自动创建整数分区

2.2. 列表分区

2.2.1. 按日志级别分区

2.2.2. 按地区分区

2.3. 哈希分区

2.3.1. 按用户ID分区

2.3.2. 按订单号分区

2.3.3. 自定义hash模

3. 应用场景

3.1. 利用EXTRACT提取年份

3.2. 分区表性能对比


        

1. 基本语法

1.1. 语法一

1.1.1. 一级分区

创建分区表有2种语法,第1种:在创建普通表后面加上指定的分区信息。

CREATE TABLE 表名
(
    列名1 数据类型,
    列名2 数据类型,
    ...
)
PARTITION BY RANGE (分区键)  --要分区的列名
(
    PARTITION 分区名1 VALUES LESS THAN (分区值),  --存储的范围
    PARTITION 分区名2 VALUES LESS THAN (分区值),  --存储的范围
    ...
);

        

举个例子:创建一张列表分区,将性别分区存储

CREATE TABLE p1 (
    id int,
    name varchar(64),
    sex varchar(4)
    )
PARTITION BY LIST(sex) --指定sex列分区
    (
    PARTITION boy VALUES ('男'),  --sex为男的数据存储到该分区
    PARTITION girl VALUES ('女')  --sex为女的数据存储到该分区
    );

创建完成后包含一张分区表和n张子分区表。

        

此时向分区表插入3条数据

INSERT INTO
    p1 
VALUES
    (1, '小李', '男'),
    (2, '小张', '女'),
    (3, '小王', '男');

查询主表:存在3条数据

查询分区表p1_boy:存储性别为"男"的数据

查询分区表p1_girl:存储性别为"女"的数据

        

总结

分区表利用不同的列数据来分别存储,插入数据后不同的子分区根据自己的规则存储不同的数据。主分区可以查询所有数据,子分区只包含规则内的数据。

        

1.1.2. 二级分区

《目录1.1》描述了如何创建一个分区表(一级分区),而真实场景会使得一级分区覆盖度远远不够,所以需要使用二级分区,语法如下:

CREATE TABLE 表名(
    列名 数据类型
)
PARTITION BY RANGE (一级分区键)     --指定一级分区
SUBPARTITION BY RANGE (二级分区键)  --指定二级分区
(
    PARTITION 一级分区名 VALUES LESS THAN (分区值)
    (
        SUBPARTITION 二级分区名 VALUES LESS THAN (分区值)
    )
);
  • PARTITION BY:普通分区语法
  • SUBPARTITION BY:子分区语法

注意:KingbasES的MySQL、Oracle模式最大支持二级分区,PG模式无限层级。

        

举个例子,年份作为一级分区、月份作为二级分区

CREATE TABLE sales_data_two_level (
    sale_date DATE,        --销售日期
    amount DECIMAL(10,2)   --销售金额
)
PARTITION BY RANGE (sale_date)    --将销售日期分区
SUBPARTITION BY RANGE (sale_date) --作一级分区
(
    /*一级分区为2020-01-01以前*/
    PARTITION p2019 VALUES LESS THAN ('2020-01-01')
    (
        /*二级分区,按月份分区*/
        SUBPARTITION p201901 VALUES LESS THAN ('2019-02-01'),
        SUBPARTITION p201902 VALUES LESS THAN ('2019-03-01'),
        SUBPARTITION p201903 VALUES LESS THAN ('2019-04-01'),
        SUBPARTITION p201904 VALUES LESS THAN ('2019-05-01'),
        SUBPARTITION p201905 VALUES LESS THAN ('2019-06-01'),
        SUBPARTITION p201906 VALUES LESS THAN ('2019-07-01'),
        SUBPARTITION p201907 VALUES LESS THAN ('2019-08-01'),
        SUBPARTITION p201908 VALUES LESS THAN ('2019-09-01'),
        SUBPARTITION p201909 VALUES LESS THAN ('2019-10-01'),
        SUBPARTITION p201910 VALUES LESS THAN ('2019-11-01'),
        SUBPARTITION p201911 VALUES LESS THAN ('2019-12-01'),
        SUBPARTITION p201912 VALUES LESS THAN ('2020-01-01')
    ),

    /*一级分区,2020-01-01 ~ 2020-12-31*/
    PARTITION p2020 VALUES LESS THAN ('2021-01-01')
    (
        /*二级分区,按月份分区*/
        SUBPARTITION p202001 VALUES LESS THAN ('2020-02-01'),
        SUBPARTITION p202002 VALUES LESS THAN ('2020-03-01'),
        SUBPARTITION p202003 VALUES LESS THAN ('2020-04-01'),
        SUBPARTITION p202004 VALUES LESS THAN ('2020-05-01'),
        SUBPARTITION p202005 VALUES LESS THAN ('2020-06-01'),
        SUBPARTITION p202006 VALUES LESS THAN ('2020-07-01'),
        SUBPARTITION p202007 VALUES LESS THAN ('2020-08-01'),
        SUBPARTITION p202008 VALUES LESS THAN ('2020-09-01'),
        SUBPARTITION p202009 VALUES LESS THAN ('2020-10-01'),
        SUBPARTITION p202010 VALUES LESS THAN ('2020-11-01'),
        SUBPARTITION p202011 VALUES LESS THAN ('2020-12-01'),
        SUBPARTITION p202012 VALUES LESS THAN ('2021-01-01')
    ),

    /*一级分区,存储2020-12-31以后的数据*/
    PARTITION p_future VALUES LESS THAN (MAXVALUE)
    (
        SUBPARTITION p_future_month VALUES LESS THAN (MAXVALUE)
    )
);

        

1.2. 语法二

1.2.1. 一级分区

  • 这种语法来自于PG语法,与上述类似,将分区表和子分区分开创建。

创建范围分区

--创建范围分区表
CREATE TABLE t1(
    id int
) PARTITION BY RANGE(id);

--创建子分区,将1~4的数值存储到t1_p1
CREATE TABLE t1_p1 PARTITION OF t1 FOR VALUES FROM(1) TO (5);
--创建子分区,将大于4的数值存储到t1_max
CREATE TABLE t1_max PARTITION OF t1 FOR VALUES FROM(5) TO (maxvalue);

        

创建列表分区

--创建列表分区表
CREATE TABLE t1(
    id int,
    sex varchar(4)
) PARTITION BY LIST(sex);

--创建子分区,将性别为男存储到t1_boy
CREATE TABLE t1_boy PARTITION OF t1 FOR VALUES IN ('男');
--创建子分区,将性别为女存储到t1_girl
CREATE TABLE t1_girl PARTITION OF t1 FOR VALUES IN ('女');

        

 创建哈希分区

--创建列表分区表
CREATE TABLE t1(
    id int
) PARTITION BY HASH(id);

--创建子分区,存储模为3余数为0的数据
CREATE TABLE t1_h1 PARTITION OF t1 FOR VALUES WITH(modulus 3, remainder 0);

        

1.2.2. 二级分区

二级分区在一级分区的基础上增加

CREATE TABLE p1 (
    id int,
    name varchar(64),
    sex varchar(4)
    )
PARTITION BY LIST(sex); --指定sex列分区

--创建一级子分区,将id列指定为范围分区
CREATE TABLE p1_boy PARTITION OF p1 FOR VALUES IN ('男') PARTITION BY RANGE(id);

--创建二级子分区,目标表为p1_boy(作为它的二级分区),分区数据为id列1~10
CREATE TABLE p1_boy_id10 PARTITION OF p1_boy FOR VALUES FROM (1) TO (11) ;

创建多个子分区根据上述语法继续写,例如:

--创建一级子分区
CREATE TABLE p1_girl PARTITION OF p1 FOR VALUES IN ('女') PARTITION BY RANGE(id);

--创建二级子分区
CREATE TABLE p1_girl_id10 PARTITION OF p1_girl FOR VALUES FROM (1) TO (11) ;

--创建二级子分区
CREATE TABLE p1_girl_id_max PARTITION OF p1_girl FOR VALUES FROM (11) TO (MAXVALUE) ;

         

2. 分区类型

在目录1中理解了如何创建分区,那么分区的类型在这一目录介绍,包括:

  • 范围分区:数值范围、日期范围等。
  • 列表分区:固定列表值,如['北京', '上海']。
  • 哈希分区:基于用户指定分区键上的哈希算法,自动将各个分区中均匀分布。

它们的语法在 PARTITION BY 后面

PARTITION BY RANGE(分区键)  --范围分区
PARTITION BY LIST(分区键)   --列表分区
PARTITION BY HASH(分区键)   --哈希分区

        

2.1. 范围分区

范围分区是根据列的范围值将表数据分布到不同的分区中,常见的日期范围、数值范围等。

语法:

PARTITION BY RANGE (列名)(
    PARTITION 分区名 VALUES LESS THAN (范围)
)

2.1.1. 按金额范围分区

CREATE TABLE orders1 (
    order_id INT PRIMARY KEY,    --订单ID
    order_date DATE,             --订单日期
    customer_id INT,             --客户ID
    total_amount DECIMAL(10, 2)  --总金额
)
PARTITION BY RANGE (total_amount) (  --将总金额分区
    PARTITION p_1 VALUES LESS THAN (1000),     --存储<1000
    PARTITION p_2 VALUES LESS THAN (10000),    --存储<1w
    PARTITION p_3 VALUES LESS THAN (100000),   --存储<10w
    PARTITION p_max VALUES LESS THAN (MAXVALUE)  --存储>=10w
);

p_1范围:0~999

p_2范围:1000~9999

p_3范围:10000~99999

p_max范围:100000~最大值

        

2.1.2. 按日期分区

CREATE TABLE sales_orders (
    order_id INT PRIMARY KEY,    --订单ID
    order_date DATE,             --订单日期
    customer_id INT,             --客户ID
    total_amount DECIMAL(10, 2)  --总金额
)
PARTITION BY RANGE (order_date) (        --将订单日期分区
    PARTITION p2019 VALUES LESS THAN ('2020-01-01'),
    PARTITION p2020 VALUES LESS THAN ('2021-01-01'),
    PARTITION p2021 VALUES LESS THAN ('2022-01-01'),
    PARTITION p2022 VALUES LESS THAN ('2023-01-01'),
    PARTITION p_max VALUES LESS THAN (MAXVALUE)
);

p2019范围:2020以前

p2020范围:2020年日期

p2021范围:2021年日期

p2022范围:2022年日期

p_max范围:2023年~以后

        

2.1.3. 自动创建日期分区

CREATE TABLE sales_orders (
    order_id INT PRIMARY KEY,    --订单ID
    order_date DATE,             --订单日期
    customer_id INT,             --客户ID
    total_amount DECIMAL(10, 2)  --总金额
)
PARTITION BY RANGE (order_date) INTERVAL('3 MONTH'::INTERVAL)  --自动创建
(
    PARTITION p1 VALUES LESS THAN ('2020-01-01')  --小于等于2020-01-01存储到p1
);

p1存储2020-01-01以前的数据,后面插入的数据每隔3个月自动创建分区

  • '1 YEAR':每隔1年创建一个分区
  • '1 MONTH':每个1个月创建一个分区
  • '1 DAY':每个1天创建一个分区

        

2.1.4. 自动创建整数分区

CREATE TABLE sales_orders (
    order_id INT PRIMARY KEY,    -- 订单ID
    order_date DATE,             -- 订单日期
    customer_id INT,             -- 客户ID
    total_amount DECIMAL(10, 2)  -- 总金额
)
PARTITION BY RANGE (order_id)INTERVAL('1000'::BIGINT)  --自动创建
(
    PARTITION p0 VALUES LESS THAN (0)  --小于等于0存储到p0
);
  • '1000'::BIGINT:数字每增长1000自动创建1个分区,也就是说插入 order_id 列 2000 后自动创建1个分区,3000、4000...同理。

        

2.2. 列表分区

列表分区不同于范围,而是将每个分区基于列值的列表。比如指定列表为 ('aa', 'bb'),那么只会将该列为 aa 或 bb 值存储到指定分区中。

语法:

PARTITION BY LIST (列名)(
    PARTITION 分区名 VALUES ('固定值1', '固定值2'),
)

2.2.1. 按日志级别分区

CREATE TABLE log_entries (
    log_id SERIAL PRIMARY KEY, --日志ID
    log_message TEXT,          --日志信息
    log_date TIMESTAMP,        --日志日期
    log_type VARCHAR(50)       --日志类型
)
PARTITION BY LIST (log_type)   --将日志类型分区
(
    PARTITION type_error VALUES ('ERROR', 'CRITICAL'),
    PARTITION type_warning VALUES ('WARNING'),
    PARTITION type_info VALUES ('INFO', 'DEBUG')
);
  • 将 'ERROR'、'CRITICAL' 存储到 type_error 中
  • 将 'WARNING' 存储到 type_warning 
  • 将 'INFO'、'DEBUG' 存储到 type_info 中
  • 其他类型无法插入

        

2.2.2. 按地区分区

CREATE TABLE sales_orders (
    order_id SERIAL PRIMARY KEY,  --订单ID
    order_date DATE,              --订单日期
    customer_id INT,              --客户ID
    total_amount DECIMAL(10, 2),  --总金额
    region VARCHAR(50)            --地区
)
PARTITION BY LIST (region)
(
    PARTITION First_tier VALUES ('北京', '上海', '广州', '深圳'),
    PARTITION second_tier VALUES ('天津', '南京', '杭州', '成都'),
    PARTITION third_tier VALUES ('哈尔滨', '福州', '长春', '石家庄')
);
  • 将一线城市分区到 First_tier
  • 将二线城市分区到 second_tier
  • 将三线城市分区到 third_tier

        

2.3. 哈希分区

    哈希分区是基于用户指定分区键上的哈希算法,数据库自动将各个分区中均匀分布,可用于划分大表,提高可管理性。当查询需要扫描整个表时,数据在各个分区上分布均匀,可以有效地利用并行查询来加速查询操作,提高查询性能。例如:将一张频繁更新的表创建为哈希分区,一张表被分为几个部分后,则这几个分区可以被同时更新,以减少锁冲突次数。

语法:

PARTITION BY HASH (列名) PARTITIONS 分区数;

        

2.3.1. 按用户ID分区

CREATE TABLE users (
    user_id INT PRIMARY KEY,  --用户ID
    username VARCHAR(50),     --用户名
    email VARCHAR(100)        --用户邮箱
) PARTITION BY HASH (user_id) PARTITIONS 4;  --将用户ID分4个区
  • PARTITIONS 4:表示分4个区

        

2.3.2. 按订单号分区

CREATE TABLE product_orders (
    order_id INT PRIMARY KEY,  --订单ID
    product_id INT,            --产品ID
    quantity INT,              --产品数量
    order_date DATE            --订单日期
) PARTITION BY HASH (order_id) PARTITIONS 8;  --将订单ID分8个区
  • PARTITIONS 8:表示分8个区

        

2.3.3. 自定义hash模

CREATE TABLE t1(
    id INT
) PARTITION BY HASH (id);

CREATE TABLE t1_hash_m3_r0 PARTITION OF t1 FOR VALUES WITH(modulus 3, remainder 0);
CREATE TABLE t1_hash_m3_r1 PARTITION OF t1 FOR VALUES WITH(modulus 3, remainder 1);
CREATE TABLE t1_hash_m3_r2 PARTITION OF t1 FOR VALUES WITH(modulus 3, remainder 2);

创建完成后会存在如下4张表:

向 t1 表插入数值 3。按正常来讲 3 的模是0,应该插入到 t1_hash_m3_r0,实际上插入在 t1_hash_m3_r1 中

这里的模并不是平时数学中的模,是通过哈希算法得出的结果:

SELECT ora_hash(3, 3);

        

3. 应用场景

3.1. 利用EXTRACT提取年份

正常情况下创建一个日期分区

CREATE TABLE sales (
    id SERIAL PRIMARY KEY,  --销售ID
    sale_date DATE          --销售日期
) PARTITION BY RANGE (sale_date);

CREATE TABLE sales_2019 PARTITION OF sales FOR VALUES FROM ('2019-01-01') TO ('2020-01-01');
CREATE TABLE sales_2020 PARTITION OF sales FOR VALUES FROM ('2020-01-01') TO ('2021-01-01');
CREATE TABLE sales_2021 PARTITION OF sales FOR VALUES FROM ('2021-01-01') TO ('2022-01-01');
  • 自动将sale_date列2019年的数据存储到sales_2019表
  • 自动将sale_date列2020年的数据存储到sales_2020表
  • 自动将sale_date列2021年的数据存储到sales_2021表

        

利用EXTRACT函数创建年份分区(在创建子分区时可以简写)

CREATE TABLE sales (
    id SERIAL PRIMARY KEY,  --销售ID
    sale_date DATE          --销售日期
) PARTITION BY RANGE (EXTRACT(YEAR FROM sale_date));

CREATE TABLE sales_2019 PARTITION OF sales FOR VALUES FROM (2019) TO (2020);
CREATE TABLE sales_2020 PARTITION OF sales FOR VALUES FROM (2020) TO (2021);
CREATE TABLE sales_2021 PARTITION OF sales FOR VALUES FROM (2021) TO (2022);
  • 存储信息与案例一相同,写法不同 

        

EXTRACT的各种用法

EXTRACT(类型 FROM 列名)
类型如下:/*
    YEAR:提取年份部分
    QUARTER:提取季度部分
    MONTH:提取月份部分
    DAY:提取日期中的天部分
    HOUR:提取小时部分
    MINUTE:提取分钟部分
    SECOND:提取秒部分  */

提取年份、季度、月份,在创建子分区时直接使用数值 

CREATE TABLE sales (
    id SERIAL PRIMARY KEY,  --销售ID
    sale_date DATE          --销售日期
) PARTITION BY RANGE (
    EXTRACT(YEAR FROM sale_date),     --年份
    EXTRACT(QUARTER FROM sale_date),  --季度
    EXTRACT(MONTH FROM sale_date)     --月份
);

/*2020年子分区*/
CREATE TABLE sales_2020_q1_m1 PARTITION OF sales FOR VALUES FROM (2020, 1, 1) TO (2020, 1, 2);
CREATE TABLE sales_2020_q1_m2 PARTITION OF sales FOR VALUES FROM (2020, 1, 2) TO (2020, 1, 3);
CREATE TABLE sales_2020_q1_m3 PARTITION OF sales FOR VALUES FROM (2020, 1, 3) TO (2020, 1, 4);
CREATE TABLE sales_2020_q2_m4 PARTITION OF sales FOR VALUES FROM (2020, 2, 4) TO (2020, 2, 5);
CREATE TABLE sales_2020_q2_m5 PARTITION OF sales FOR VALUES FROM (2020, 2, 5) TO (2020, 2, 6);
CREATE TABLE sales_2020_q2_m6 PARTITION OF sales FOR VALUES FROM (2020, 2, 6) TO (2020, 2, 7);
CREATE TABLE sales_2020_q3_m7 PARTITION OF sales FOR VALUES FROM (2020, 3, 7) TO (2020, 3, 8);
CREATE TABLE sales_2020_q3_m8 PARTITION OF sales FOR VALUES FROM (2020, 3, 8) TO (2020, 3, 9);
CREATE TABLE sales_2020_q3_m9 PARTITION OF sales FOR VALUES FROM (2020, 3, 9) TO (2020, 3, 10);
CREATE TABLE sales_2020_q4_m10 PARTITION OF sales FOR VALUES FROM (2020, 4, 10) TO (2020, 4, 11);
CREATE TABLE sales_2020_q4_m11 PARTITION OF sales FOR VALUES FROM (2020, 4, 11) TO (2020, 4, 12);
CREATE TABLE sales_2020_q4_m12 PARTITION OF sales FOR VALUES FROM (2020, 4, 12) TO (2021, 1, 1);

/*2021年子分区*/
CREATE TABLE sales_2021_q1_m1 PARTITION OF sales FOR VALUES FROM (2021, 1, 1) TO (2021, 1, 2);
CREATE TABLE sales_2021_q1_m2 PARTITION OF sales FOR VALUES FROM (2021, 1, 2) TO (2021, 1, 3);
CREATE TABLE sales_2021_q1_m3 PARTITION OF sales FOR VALUES FROM (2021, 1, 3) TO (2021, 1, 4);
CREATE TABLE sales_2021_q2_m4 PARTITION OF sales FOR VALUES FROM (2021, 2, 4) TO (2021, 2, 5);
CREATE TABLE sales_2021_q2_m5 PARTITION OF sales FOR VALUES FROM (2021, 2, 5) TO (2021, 2, 6);
CREATE TABLE sales_2021_q2_m6 PARTITION OF sales FOR VALUES FROM (2021, 2, 6) TO (2021, 2, 7);
CREATE TABLE sales_2021_q3_m7 PARTITION OF sales FOR VALUES FROM (2021, 3, 7) TO (2021, 3, 8);
CREATE TABLE sales_2021_q3_m8 PARTITION OF sales FOR VALUES FROM (2021, 3, 8) TO (2021, 3, 9);
CREATE TABLE sales_2021_q3_m9 PARTITION OF sales FOR VALUES FROM (2021, 3, 9) TO (2021, 3, 10);
CREATE TABLE sales_2021_q4_m10 PARTITION OF sales FOR VALUES FROM (2021, 4, 10) TO (2021, 4, 11);
CREATE TABLE sales_2021_q4_m11 PARTITION OF sales FOR VALUES FROM (2021, 4, 11) TO (2021, 4, 12);
CREATE TABLE sales_2021_q4_m12 PARTITION OF sales FOR VALUES FROM (2021, 4, 12) TO (2022, 1, 1);

        

3.2. 分区表性能对比

  • 简介中说到了分区表性能比普通表更好,这里直接举例说明

1、创建一张分区表,数据100w行,每个分区存储1w行,共100分区

--创建一个按数值自动分区的分区表,每1w行自动分1个区
CREATE TABLE t1 (
    c1 INT,
    c2 TEXT
)
PARTITION BY RANGE (c1)INTERVAL('10000'::BIGINT)
(
    PARTITION p0 VALUES LESS THAN (0)
);

--插入100w行数据
INSERT INTO t1 VALUES(generate_series(1, 1000000), md5(random()));

         

2、创建一张普通表,数据100w行,结构与分区表一样

CREATE TABLE t2 (
    c1 INT,
    c2 TEXT
);
INSERT INTO t2 VALUES(generate_series(1, 1000000), md5(random()));

        

执行t1和t2的查询语句

explain analyze select * from t1 where c1 = 900000;
explain analyze select * from t2 where c1 = 900000;

结果如下:

kingbase=# explain analyze select * from t1 where c1 = 900000;
                                            QUERY PLAN
---------------------------------------------------------------------------------------------------
 Seq Scan on t1_p91  (cost=0.00..210.00 rows=1 width=37) (actual time=0.020..0.777 rows=1 loops=1)
   Filter: (c1 = 900000)
   Rows Removed by Filter: 9999
 Planning Time: 28.207 ms
 Execution Time: 0.895 ms
(5 rows)

kingbase=# explain analyze select * from t2 where c1 = 900000;
                                                    QUERY PLAN
------------------------------------------------------------------------------------------------------------------
 Gather  (cost=1000.00..14612.43 rows=1 width=37) (actual time=94.872..120.737 rows=1 loops=1)
   Workers Planned: 2
   Workers Launched: 2
   ->  Parallel Seq Scan on t2  (cost=0.00..13612.33 rows=1 width=37) (actual time=31.346..35.375 rows=0 loops=3)
         Filter: (c1 = 900000)
         Rows Removed by Filter: 333333
 Planning Time: 0.150 ms
 Execution Time: 120.775 ms
(8 rows)

    如上:分区表成本 0.777,普通表成本 120.737。从100w数据耗时看,分区表性能是普通表的155倍,那么为什么性能提升这么多呢?

    从t1表的扫描结果来看,查询的是 t1_p91 表,这张表仅存储1w行数据。而普通表t2扫描的是全表(100w行),相较之下,分区表自然快得多。

    需要注意的是,这个例子没有索引,当加上索引后若非超大数据,分区表与普通表性能相差无几。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值