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

一、前言

目前已知qt使用数据库有两种存储数据的方式,一种是采用QSqlTableModel方式,还有一种是insert语句方式,一直用的数据量比较小,所以一直采用QSqlTableModel方式,偶然做项目,采用了大数据存储,发现QSqlTableModel方式就出现bug了,在一直循环上传数据条目时,连续5900+条时就会导致程序崩溃,多次反复测试都是这个问题,也不知道具体原因,所以想到了第二种方式,采用之后测试一下果然没有问题,连续运行存储7w+条也正常,今天把两种方式都分享出来,一直也没具体写过数据库操作的文章。

二、环境

qt5.7 mingw window8

三、正文

QSqlTableModel方式: 

QSqlTableModel *model = new QSqlTableModel(NULL, db);
model->setTable("data");
model->setEditStrategy(QSqlTableModel::OnManualSubmit);
model->select();
QSqlRecord record = model->record();
QString title[11]={"time","AI1","AI2","AI3","AI4","AI5","AI6","AI7","AI8","AI9","AI10"};
record.setValue(title[0],QDateTime::currentDateTime().toString("yyMMddHHmmsszzz"));
for(int i=0;i<10;i++)record.setValue(title[i+1],QString::number(AIvalue[i]));
model->insertRecord(0, record);
model->submitAll();

insert方式:

QSqlQuery query(db);
QString mInsertStr = QString("INSERT INTO data (time,AI1,AI2,AI3) VALUES ('%1','%2','%3','%4');").arg(QDateTime::currentDateTime().toString("yyMMddHHmmsszzz")).arg(QString::number(AIvalue[0])).arg(QString::number(AIvalue[1])).arg(QString::number(AIvalue[2]));
query.prepare(mInsertStr);
query.exec();

 或

QSqlQuery query(db);
query.exec(QString("INSERT INTO Sys_journal(date,note) VALUES ('%1','%2');").arg(date).arg(sqlnote));

事务方式(抄):

1.SQLite数据库本质上来讲就是一个磁盘上的文件,所以一切的数据库操作其实都会转化为对文件的操作,而频繁的文件操作将会是一个很好时的过程,会极大地影响数据库存取的速度。例如:向数据库中插入100万条数据,在默认的情况下如果仅仅是执行query.exec(“insert into DataBase(……) values(……)”);就会打开和关闭文件100万次,所以速度当然会很慢。

2.SQLite数据库是支持事务操作的,于是我们就可以通过事务来提高数据库的读写速度。事务的基本原理是:数据库管理系统首先会把要执行的sql语句存储到内存当中,只有当commit()的时候才一次性全部执行所有内存中的数据库。

不用事务
如果不用事务,插入1000条数据到sqlite数据库,要执行1000次开启事务、结束事务,大致意思如下图: 


使用事务
如果使用事务,存储1000条数据到sqlite数据库,只需要执行一次开启事务、结束事务操作,大致意思如下图: 
 
时间成本应该就是节约在多余的开启事务和结束事务这里。

口说无凭,下面上截图,大致存储了6000条数据,使用事务之前,需要花费7分钟左右,下面是使用事务之后,仅仅用了2秒钟: 


Qt中使用事务的大致方法:
db.transaction(); 
执行插入的sql(n条插入操作) 
db.commit();

实例
下面是一段我写的代码,insert是我封装的一个执行sql语句的接口: 
/添加数据到XXX表/

bool DbManager::appendData2MfCali(const QList<MfCalibrate> &data)
{
    if(data.isEmpty())
        return false;

    mDb->beginTransaction(); //开启事务
    foreach (MfCalibrate v, data)
    {
        QVector<QString> fieldValue;
        fieldValue.append(QString::number(v.RfChannel));     
        fieldValue.append(QString::number(v.MfChannel));     
        fieldValue.append(QString::number(v.RfFreq));       
        fieldValue.append(QString::number(v.CollectValue));  
        fieldValue.append(QString::number(v.AmpCaliValue));  
        if(!mDb->insert("XXX表",mMfCaliFieldsName , fieldValue))
            return false;
    }
    mDb->commitTransaction(); //提交
    return true;
}

事务方式是抄的,也是学到了自己就不重复总结啦,嘿嘿!
 

四、结语

更多通过语句操作数据库的方式参照此贴Qt之操作数据库(SQLite) - Avatarx - 博客园

  • 1
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大桶矿泉水

你的鼓励是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值