好久没有接触数据库了,最近因为工作的原因,又开始在Qt上使用数据库,这次主要用的是Qt自带的sqlite,使用方便简单。
项目需求:需要实时存储网络报文数据,并能实时查询,查询时要求全部查询或自定义查询,且都具有翻页、跳转等功能。
实现过程中遇到了以下问题:
- 网络报文是实时的,且数量不定,故一条一条进行存储效率太低;
- 翻页显示时,界面要求只能显示最多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. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载
声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性