好久没有接触数据库了,最近因为工作的原因,又开始在Qt上使用数据库,这次主要用的是Qt自带的sqlite,使用方便简单。

项目需求:需要实时存储网络报文数据,并能实时查询,查询时要求全部查询或自定义查询,且都具有翻页、跳转等功能。

实现过程中遇到了以下问题:

  1. 网络报文是实时的,且数量不定,故一条一条进行存储效率太低;
  2. 翻页显示时,界面要求只能显示最多25条数据,随着数据量增到,使用limit进行分页,检索效率越来越低。

针对问题一:

经查询资料,决定采用事务的方式进行存储,即使用db.transaction()。但是这种方式支持大批量的数据,且在进行执行事务时,不支持多线程同时读写。

故在实现时,采用定时器,先将网络报文进行临时存储,当定时器溢出时,将缓存数据一次性存储到数据库中。由于项目中建立了2个线程,一个写,一个读,由于采用事务机制,不支持同时读写,需要在线程加上互斥锁进行保护。


 1 bool status = true;
 2 db.transaction();
 3 QSqlQuery query(db)
 4 query.prepare("INSERT INTO data_log(timeStamp,pipe,topic,srcType)VALUES (:timeStamp,:pipe,:topic,:srcType)"
 5 for(int i=0;i<num,i++)
 6 {
 7    LOGMSG log = dataList[i];//dataList缓存了要存的数据内容    
 8    query.bindValue(":srcType",log.srcType);
 9    //省略,主要是进行参数绑定
10    query.bindValue(":timeStamp",static_cast<int>(log.TimeStamp));
11    status = query.exec();
12    if(!status)
13    {
14         qDebug()<<"addData db exec() is error!<<endl;
15         qDebug()<<query.lastError().text()<<endl;
16         db.rollback();
17         return;
18    }
19    query.finish();
20 
21 }
22 db.commit();//提交事务
23 dataList.remove(0,num);

View Code

 

针对问题二:

为了实现分页功能,刚开始采用的SQL语句如下:

select * from data_log limit 偏移量起始位置,条数
// 举例
query.prepare("select * from data_log limit "+QString::number(CurrentItem)+","+QString::number(PAGE_NUMBER));

但是随着数据量越来越大,偏移量的值也越来越大,检索效率越来越低,故将SQL语句优化如下:

 

select * from data_log where id>=偏移量 limit 条数
//举例
query.prepare(QString("select * from data_log where id>= %1 limit %2").arg(CurrentItem-1).arg(PAGE_NUMBER));

检索效率明显提升!(当然这里有个前提,创建数据库时,id为主键,且为AUTOINCREMENT)

检索效率差,除了优化SQL语句,建立索引也是一种好方法,效果也很明显,这里不再赘述。

 

原文地址:http://www.cnblogs.com/ycbeginner/p/16894279.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性