Sqlite大批量导入数据提高效率的几种方式

SQLite批量插入效率 SQLite对于大批量插入数据时的效率提升方法 阅读详情
AI摘要

本文介绍通过使用事务、调整写同步选项及执行准备等方法显著提高SQLite数据库数据插入速度的技术细节。

前言

SQLite数据库由于其简单、灵活、轻量、开源,已经被越来越多的被应用到中小型应用中。甚至有人说,SQLite完全可以用来取代c语言中的文件读写操作。因此我最近编写有关遥感数据处理的程序的时候,也将SQLite引入进来,以提高数据的结构化程度,并且提高大数据的处理能力(SQLite最高支持2PB大小的数据)。但是最开始,我发现,直接使用SQL语句的插入效率简直低的令人发指的。后来不断查文档、查资料,才发现了一条快速的“数据插入”之路。本文就以插入数据为例,整合网上和资料书中的各种提高SQLite效率的方法,给出提高SQLite数据插入效率的完整方法。

 

1 数据

我使用的电脑是Win7 64位系统,使用VC2010编译,SQLIte版本为3.7.15.2 ,电脑CPU为二代i3处理器,内存6G。

实验之前,先建立要插入数据的表:

create table t1 (id integer , x integer , y integer, weight real)  

2 慢速——最粗暴的方法

SQLite的API中直接执行SQL的函数是:
int sqlite3_exec(  sqlite3*,    const char *sql,   int (*callback)(void*,int,char**,char**),   void *,   char **errmsg)  

直接使用INSERT语句的字符串进行插入,程序部分代码(完整代码见后文),如下

 

for(int i=0;i<nCount;++i)  
{  
     std::stringstream ssm;  
     ssm<<"insert into t1 values("<<i<<","<<i*2<<","<<i/2<<","<<i*i<<")";  
     sqlite3_exec(db,ssm.str().c_str(),0,0,0);  
}  

 

这个程序运行的太慢了,我已经没时间等待了,估算了一下,基本上是 7.826 条/s

3 中速——显式开启事务

所谓”事务“就是指一组SQL命令,这些命令要么一起执行,要么都不被执行。在SQLite中,每调用一次sqlite3_exec()函数,就会隐式地开启了一个事务,如果插入一条数据,就调用该函数一次,事务就会被反复地开启、关闭,会增大IO量。如果在插入数据前显式开启事务,插入后再一起提交,则会大大提高IO效率,进而加数据快插入速度。

开启事务只需在上述代码的前后各加一句开启与提交事务的命令即可:

 

sqlite3_exec(db,"begin;",0,0,0);  
for(int i=0;i<nCount;++i)  
{  
    std::stringstream ssm;  
    ssm<<"insert into t1 values("<<i<<","<<i*2<<","<<i/2<<","<<i*i<<")";  
    sqlite3_exec(db,ssm.str().c_str(),0,0,0);  
}  
sqlite3_exec(db,"commit;",0,0,0); 

 

显式开启事务后,这个程序运行起来明显快很多,估算效率达到了34095条/s,较原始方法提升约5000倍。

4 高速——写同步(synchronous)

我要使用一个遥感处理算法处理10000*10000的影像,中间有一步需要插入100000000条数据到数据库中,如果按照开启事务后的速度34095条/s,则需要100000000÷34095 = 2932秒 = 48.9分,仍然不能够接受,所以我接着找提升速度的方法。终于,在有关讲解SQLite配置的资料中,看到了“写同步”选项。

在SQLite中,数据库配置的参数都由编译指示(pragma)来实现的,而其中synchronous选项有三种可选状态,分别是full、normal、off。这篇博客以及官方文档里面有详细讲到这三种参数的设置。简要说来,full写入速度最慢,但保证数据是安全的,不受断电、系统崩溃等影响,而off可以加速数据库的一些操作,但如果系统崩溃或断电,则数据库可能会损毁。

SQLite3中,该选项的默认值就是full,如果我们再插入数据前将其改为off,则会提高效率。如果仅仅将SQLite当做一种临时数据库的话,完全没必要设置为full。在代码中,设置方法就是在打开数据库之后,直接插入以下语句:

sqlite3_exec(db,"PRAGMA synchronous = OFF; ",0,0,0); 

此时,经过测试,插入速度已经变成了41851条/s,也就是说,插入100000000条数据,需要2389秒 = 39.8分

5 极速——执行准备

虽然写同步设为off后,速度又有小幅提升,但是仍然较慢。我又一次踏上了寻找提高SQLite插入效率方法的道路上。终于,我发现,SQLite执行SQL语句的时候,有两种方式:一种是使用前文提到的函数sqlite3_exec(),该函数直接调用包含SQL语句的字符串;另一种方法就是“执行准备”(类似于存储过程)操作,即先将SQL语句编译好,然后再一步一步(或一行一行)地执行。如果采用前者的话,就算开起了事务,SQLite仍然要对循环中每一句SQL语句进行“词法分析”和“语法分析”,这对于同时插入大量数据的操作来说,简直就是浪费时间。因此,要进一步提高插入效率的话,就应该使用后者。

“执行准备”主要分为三大步骤:

1.调用函数:

int sqlite3_prepare_v2( sqlite3 *db,  const char *zSql,  int nByte,  sqlite3_stmt **ppStmt,  const char **pzTail);

并且声明一个指向sqlite3_stmt对象的指针,该函数对参数化的SQL语句zSql进行编译,将编译后的状态存入ppStmt中。

2.调用函数 sqlite3_step() ,这个函数就是执行一步(本例中就是插入一行),如果函数返回的是SQLite_ROW则说明仍在继续执行,否则则说明已经执行完所有操作;

3.调用函数 sqlite3_finalize(),关闭语句。

关于执行准备的API的具体语法,详见官方文档。本文中执行准备的c++代码如下:

 

sqlite3_exec(db,"begin;",0,0,0);  
sqlite3_stmt *stmt;  
const char* sql = "insert into t1 values(?,?,?,?)";  
sqlite3_prepare_v2(db,sql,strlen(sql),&stmt,0);  
  
for(int i=0;i<nCount;++i)  
{         
    sqlite3_reset(stmt);  
    sqlite3_bind_int(stmt,1,i);  
    sqlite3_bind_int(stmt,1,i*2);  
    sqlite3_bind_int(stmt,1,i/2);  
    sqlite3_bind_double(stmt,1,i*i);  
}  
sqlite3_finalize(stmt);  
sqlite3_exec(db,"commit;",0,0,0);  

 

此时测试数据插入效率为:265816条/s,也就是说,插入100000000条数据,需要376秒 = 6.27分。这个速度已经很满意了。

 

综上所述啊,SQLite插入数据效率最快的方式就是:事务+关闭写同步+执行准备(存储过程),如果对数据库安全性有要求的话,就开启写同步。

 6 使用WAL模式

   (1).WAL:Write Ahead Logging,他是数据库中用于实现原子事务的一种机制,从3.7.0版本后引入

   (2).WAL模式主要有两个优点:

      a.读写可以完全并发进行,不会互相阻塞(但是写之间仍然不能并发)

     b.WAL在大多情况下,拥有更好的性能(因为无需每次写入时都要写两个文件)

   (3).Rollback journal机制原理:在修改数据库中的数据前,先将修改所在分页中的数据备份在另一个地方,然后再将修改写入到数据中;如果事务失败,则将备份数据拷贝回来,撤销修改;如果事务成功,则删除备份,提交修改。

   (4).WAL机制原理:修改并不直接写入到数据库文件中,而是写入到另外一个称为WAL的文件中,如果事务失败,wal中的文件会被忽略,撤销修改;如果事务成功,它将在随后的某个时间被写回到数据库文件中,提交修改。

   性能差异主要源于每次事务提交,wal只需要将更新的日志写入磁盘,而delete模式首先要将原始数据拷贝到日志文件中,并进行fsync,然后将修改页写入磁盘,同时也需要fsync,确保数据落盘,并且还要清除日志文件。因此写事务在WAL模式下,只需要一次    fsync,并且是顺序写,而在delete模式下需要至少两次fsync(日志,数据),并且更新的数据离散分布在多个page中,因此可能需要多个fsync。

   WAL使用共享内存技术,因此所有读写进程必须在同一个机器上

   开启WAL模式的方法: 

 View Code

  在前面的基础上,使用WAL模式后执行5次操作平均耗时4.324秒

7.内存数据库

  另外,如果数据无需长时间保存,可以使用sqlite的内存数据库替代文件数据库

  开启sqlite内存数据库的方式:

 View Code

  执行5次平均耗时:4.052秒

  但是内存数据库存在如下缺点:

  (1).断电或者程序崩溃后数据库就会消失
  (2).在内存中的数据库不能被别的进程访问

  (3).不支持像在硬盘上的读写互斥处理,需要自己加锁

8 总结

参考资料:

1. SQLite官方文档:http://www.sqlite.org/docs.html

2.《解决sqlite3插入数据很慢的问题》:http://blog.youkuaiyun.com/victoryknight/article/details/7461703

3.《The Definitive Guide to SQLite》Apress出版:http://www.apress.com/9781430232254 (这是本好书)

附最终完整代码:

 

 

#include <iostream>  
#include <string>  
#include <sstream>  
#include <time.h>  
#include "sqlite3.h"  
  
const int nCount = 500000;  
      
int main (int argc,char** argv)  
{  
    sqlite3* db;  
    sqlite3_open("testdb.db" ,&db);  
    sqlite3_exec(db,"PRAGMA synchronous = OFF; ",0,0,0);  
    sqlite3_exec(db,"drop table if exists t1",0,0,0);  
    sqlite3_exec(db,"create table t1(id integer,x integer,y integer ,weight real)",0,0,0);  
    clock_t t1 = clock();  
      
    sqlite3_exec(db,"begin;",0,0,0);  
    sqlite3_stmt *stmt;  
    const char* sql = "insert into t1 values(?,?,?,?)";  
    sqlite3_prepare_v2(db,sql,strlen(sql),&stmt,0);  
      
    for(int i=0;i<nCount;++i)  
    {  
        // std::stringstream ssm;  
        // ssm<<"insert into t1 values("<<i<<","<<i*2<<","<<i/2<<","<<i*i<<")";  
        // sqlite3_exec(db,ssm.str().c_str(),0,0,0);  
        sqlite3_reset(stmt);  
        sqlite3_bind_int(stmt,1,i);  
        sqlite3_bind_int(stmt,2,i*2);  
        sqlite3_bind_int(stmt,3,i/2);  
        sqlite3_bind_double(stmt,4,i*i);  
        sqlite3_step(stmt);  
    }  
    sqlite3_finalize(stmt);  
    sqlite3_exec(db,"commit;",0,0,0);  
    clock_t t2 = clock();  
      
    sqlite3_close(db);  
      
    std::cout<<"cost tima: "<<(t2-t1)/1000.<<"s"<<std::endl;  
      
    return 0;  
}  

 

 

Sqlite3 stmt 机制操作 参考文献:https://blog.youkuaiyun.com/u012351051/category_8966045.html 操作步骤: 阅读详情

相关推荐

qt之sqlite存储大数据(事务更快)

一、前言 目前已知qt使用数据库有两种存储数据的方式,一种是采用QSqlTableModel方式,还有一种是insert语句方式,一直用的数据量比较小,所以一直采用QSqlTableModel方式,偶然做项目,采用了大数据存储,发现QSqlTableModel方式就出现bug了,在一直循环上传数据条目时,连续5900+条时就会导致程序崩溃,多次反复测试都是这个问题,也不知道具体原因,所以想到了第...

kbq的博客 5953

SQLite批量插入

测试批量插入到SQLite的时长,共9599条数据方法1:单条进行插入,耗时约2分钟方法2:使用事务进行插入,耗时约2秒关于事务的使用步骤如下所述。

zeron01的博客 3831

QT使用SQLite 超详细(增删改查、包括对大量数据快速存储和更新)

QT+SQLite 超详细(增删改查、包括对大量数据快速存储和更新)

HXX904的博客 1万+

SQLite 数据库中如何进行大量的数据插入

在 SQLite 中进行大量数据插入时,可以通过使用事务、预处理语句、批量插入、禁用自动提交以及性能优化技巧等方式来提高效率。合理管理事务和错误处理,不仅可以提高插入性能,还能确保数据的完整性和一致性。通过本文的介绍,您应该对如何在 SQLite 中高效地进行大量数据插入有了全面的了解。在实际应用中,建议根据具体数据特点和性能需求,合理选择和组合这些方法,以实现最佳性能效果。希望这些技巧和建议能够帮助您在 SQLite 数据库管理中更有效地处理大量数据插入的需求。

My_wife_QBL的博客 5948

SQLite 的性能优化其实挺难的,但是知道三个技巧让你的应用飞起来!

最近,有个朋友问我:“为什么我的 Rails 项目用 SQLite,总觉得慢得像蜗牛?”这让我想起很多开发者在遇到类似问题时的感受,尤其是初次接触 SQLite 的时候。SQLite 作为轻量级的数据库,在 Rails 项目中非常常见,特别是开发阶段。但问题来了,SQLite 真有我们想象中那么简单吗?它的性能优化又需要注意什么呢?今天咱们就来聊聊,如何在 SQLite 上做出真正的性能提升。

知道者 945

三菱FX3U PLC红绿灯ST编程实战:从基础逻辑到急停功能完整实现

本文以十字路口红绿灯控制为例,详细讲解了三菱FX3U PLC使用ST编程的完整实战过程。内容涵盖从基础时序逻辑、状态机设计,到急停功能、黄灯闪烁、昼夜模式切换等高级功能的实现,并提供了代码优化与调试技巧,帮助工程师掌握结构化文本在工业控制中的清晰、结构化应用。

weixin_29070861的博客 532

快速插入sqlite数据库的几种方法比较

sqlite

weixin_44216359的博客 2676

6、基于深度强化学习的无人机路径规划

本文介绍了一种结合人工势场法的改进DQN深度强化学习算法在无人机路径规划中的应用。通过设计合理的网络结构、状态空间、动作空间和融合引力-斥力机制的奖励函数,实现了无人机在复杂环境中的自主避障与目标导向飞行。采用轻量级神经网络提升实时性,并在Gazebo仿真环境中进行训练与测试,结果表明该算法具有快速收敛、高成功率和良好适应性。实验评估指标包括损失函数、最大Q值和任务成功率,验证了方法的有效性。文章还探讨了其在物流配送、农业植保和环境监测等领域的应用前景,并展望了多无人机协同与复杂环境适应性等未来研究方向。

html8的博客 237

android开发中,导入有数据的sqlite,与apk一起安装到手机上

sqlite比较常规的使用方式一般是这样的,就是在程序中新建一个空的数据库,然后进行增删改查等一系列的操作,这样的操作,对于小应用的开发是比较容易满足需求的,但是有些比较大的应用,包含的数据量比较大,如果在程序中,对数据进行一条一条的插入,第一,比较耗时,第二,用户体验很差,最重要的一点是显得很不专业。那么,可以想到的一种比较好的方式,就是如何将db文件与apk一起安装到手机上呢,实现方法如下:

ZhuaWaMi的专栏 3597

看懂特斯拉IMU底层逻辑,才懂农业机器人不可替代的核心技术壁垒

在自动驾驶与具身智能赛道,特斯拉彻底重构了IMU(惯性测量单元)的技术定位,打破行业“IMU仅为辅助补盲配件”的固有认知,将其从底盘附属硬件升级为纯视觉感知体系的物理核心基座。依托500–1000Hz超高刷新率、无外部依赖的惯性感知能力、端到端神经网络融合架构,特斯拉实现了“视觉感知环境、IMU定义运动”的技术闭环,摆脱对激光雷达、高精地图、卫星定位的强依赖。这套技术逻辑落地农业机器人赛道,不再是技术优化,而是规模化落地的生存刚需。城市自动驾驶属于结构化稳定场景,IMU仅作误差修正的锦上添花;

getusushu的博客 49

RK3588开发笔记-ES8311音频芯片调试记录

本篇博客主要记录如何在RK3588平台试ES8311音频芯片的过程。这包括硬件连接、内核配置、驱动程序调试和测试步骤。通过以上步骤,我们成功在RK3588平台上调试了ES8311音频芯片。这包括硬件连接、内核配置、设备树配置、驱动加载以及音频测试。希望这篇调试记录能为其他开发者提供一些帮助。如果你有任何问题或建议,欢迎留言讨上调论。

flypig has a dream! 3161

SQLite 3 优化批量数据存储操作---事务transaction机制

SQLite3的数据库事务transaction操作目的是为了保证数据的一致性和完整性,开启事务操作,可以提升数据库系统性能提升,优化数据错误处理机制。

weixin_49337111的博客 3247

GEE 案例分析:利用Landsat数据进行FAI、NDVI及CHLA分析并统计平均值(巢湖为例)

浮游藻类指数(FAI)、归一化植被指数(NDVI)及叶绿素a(CHLA)是水体环境监测的重要指标。本文利用Google Earth Engine(GEE)平台,基于Landsat 5和Landsat 8数据,进行水体藻类及植被监测。

此星光明博客 1336

sqlite数据库 批量导入

最近处理一个将csv内容导入到sqlite数据库中,使用了事务(BEGINTRANSACTION; sql语句;COMMIT;) 测试发现一次1000条导入,反而比10000条导入要快,总共6万多条数据,整下下来竟然快有6分钟,真是奇怪 var iCount = 0; var dDataTime = DateTime.Now; ...

weixin_30432007的博客 125

【100%通过率】华为OD机试真题 Python 实现【打印机队列】【2022.11 Q4 新题】

有5台打印机打印文件,每台打印机有自己的待打印队列。因为打印的文件内容有轻重缓急之分,所以队列中的文件有1~10不同的代先级,其中数字越大优先级越高。打印机会从自己的待打印队列中选择优先级最高的文件来打印。如果存在两个优先级一样的文件,则选择最早进入队列的那个文件。现在请你来模拟这5台打印机的打印过程。

MISAYAONE的博客 1万+

lammps案例:热导率模拟案例讲解(NEMD方法)

lammps计算热导率大体可以分为三种方法:EMD、NEMD、rNEMD。 本文介绍非平衡模拟(NEMD)热导率的计算方法。 NEMD下热导率计算公式为: k=dQ*dZ/dt k:热导率 dQ:能量通量。 dT/dZ:温度梯度。 非平衡态下计算热导率的原理是在材料的两端或者中间设置热源和冷源。 在热源输入热量,在冷源抽取等量的热量,在这个过程中计算材料内部会有热量的传递,产生温度梯度。 在lammps模拟中得到能量通量和温度梯度,代入公式即可求得热导率。 热量的输入方式有多种,如fix langevin

lammps_jiayou的博客 1万+

sqlite-php教程,PHP SQLite 简介

一、什么是 SQLiteSQLite 是一款轻型的数据库,是遵守ACID标准,它占用资源非常的低,可能只需要几百K的内存就够了。它能够支持 Windows/Linux/Unix 等等主流的操作系统,同时能够支持很多程序语言,如C、PHP、Java等。它适用于一些中小型的软件的数据库,如嵌入式开发、路由器、桌面程序。二、特点1、SQLite数据库足够小, 大致3万行C代码, 共计250K左右2、配置...

weixin_33144635的博客 382

代码的自由之旅:用AI写出无版权烦恼的Verilog

他们还基于这个数据集,训练了一个名叫“FreeV”的AI模型,不仅能写出好用的Verilog代码,还把版权侵权的风险降到了仅3%。为了让AI安全地写Verilog,研究团队提出了三个“法宝”:一个检测AI是否会生成侵权代码的测试方法、一个干净的Verilog数据集FreeSet,还有一个基于FreeSet训练的AI模型FreeV。AI的记忆力超强,能记住训练时见过的代码。测试发现,一些用Verilog数据训练过的AI,比如VeriGen,生成侵权代码的概率从9%涨到了15%,说明它们可能学了不该学的代码。

步子哥的博客 1808

SQLite数据库简介与基本使用

1.SQLite简介: SQLite是一款轻量级的开源的嵌入式数据库,由D.Richard Hipp在2000年发布。SQLite使用方便,性能出众,广泛应用于消费电子、医疗、工业控制、军事等各种领域。 2.SQLite的特点: (1)体积小:最低只需要几百K的内存就可以运行。 (2)性能高:对数据库的访问性能很高,其运行速度比Mysql等开源数据库要快很多。 (

拼命三郎 6万+

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

android sqlite 数据初始化

1. 批量导入 添加事务处理,把5000条插入作为一个事务 dataBase.beginTransaction();        //手动设置开始事务 //数据插入操作循环 dataBase.setTransactionSuccessful();        //设置事务处理成功,不设置会自动回滚不提交 dataBase.endTransaction();        //处理完成

随缘,随心 6314

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

sqlite-web 10个隐藏功能:从数据导入到高级查询的实用技巧

sqlite-web 是一款基于Web的SQLite数据库浏览器,采用Python开发,提供直观的界面帮助用户轻松管理和查询SQLite数据库。无论是数据库新手还是有经验的开发者,都能通过这款工具快速实现数据可视化、表结构管理和高级查询等操作。 ## 1. 一键导入CSV/JSON数据 数据导入功能是sqlite-web最实用的特性之一。通过简单的界面操作,即可将外部数据无缝集成到SQLite

gitblog_00080的博客 1241

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

Python 中如何使用 sqlite3 操作 SQLite 数据库?

在 Python 开发中,SQLite 是一种轻量级的关系型数据库,它无需单独安装数据库服务器,所有数据存储在一个单独的文件中,适用于小型应用、移动开发、数据分析等场景。Python 提供了内置的 `sqlite3` 模块,方便我们操作 SQLite 数据库。本文将详细介绍 `sqlite3` 模块的使用,包括数据库连接、表操作、数据增删改查(CRUD),以及常见的事务管理和参数化查询,帮助你快速掌握 Python 操作 SQLite 数据库的方法。

3185

ios 导入mysql数据库_iOS App项目中引入SQLite数据库的教程

引入SQLitesqlite是纯C实现的,所以注定了它是一个跨平台利器,在Android与IOS下均能使用,而且完全可以写出通用的代码,方便我们移植。当然Android和IOS下都有封装过的sqlite给开发者使用,不过这样子一个是不方便移植,另一个是封装后的效率咋样我们也不知道,所以还是原生态的最健康。最后一个重要的原因就是原生的使用也是相当简单。我将在接下来的教程中为您一一讲解。首先最重要的一...

weixin_26841743的博客 365

玩转SQLite-11:C语言高效API之sqlite3_prepare系列函数

SQLite是一个跨平台的轻量级数据库,支持C/C++开发,可用于嵌入式中,关于C/C++使用SQLite的简单实例,之前这篇文章,已经介绍过一种简单的使用方式。本篇来介绍另一种更加高效的调用方式。

码农爱学习的博客 4485

【用SQLite做数据分析】Python操作SQLite的入门介绍

本篇推文共计2000个字,阅读时间约3分钟。Python 进行数据分析和数据挖掘是当前炙手可热的技术领域,如何高效地管理大量数据是其中非常关键的环节。数据库是最佳的解决方案之一,目前流行...

看那个码农的博客 1073
上一篇: sqlite3:锁机制、stmt加速、wal日志模式、多进程并发、写互斥
下一篇: Windows系统内存计数器理解解析
wangjunhe
博客等级 码龄20年 31粉丝 22原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值