• 8720阅读
  • 8回复

这是QT的设计缺陷吗? [复制链接]

上一主题 下一主题
离线lxbin2003
 

只看楼主 倒序阅读 楼主  发表于: 2010-11-21
— 本帖被 yfx2003 从 《高级Qt编程》专栏 移动到本区(2010-11-22) —
QSqlTableModel query(0,db);
        query.setTable(tname);
        if(query.select())
        {
            while(query.canFetchMore())
            {
                query.fetchMore();
            }
        }
这段代码正常情况下运行没有问题,但是,当这个表的记录数很多时(比如几百万条甚至更多),程序会crash。程序占用内存量急剧上升。我分析,QSqlResult要把这些记录存在内存里,好象是使用QVector,它的上限是int型的,是内存分配失败呢,还是内存访问越界?
重载QCoreApplication::notify()可以用 try{}catch(...){}捕捉到这个错误,使程序不crash,但运行上面那段代码的函数会终止。
大家有什么好的建议吗?
如果是设计缺陷,最好有英文好的同学把这个问题反应到官方去。
离线samsam598

只看该作者 1楼 发表于: 2010-11-23
这不是设计缺陷,这是必然,很多C++数据库类封装时在这个问题上都不实现封装,原因就是你说的用容器缓存查询结果集。
一个高效的替代办法就是自已用SQL的DML。比如查询最后一条:
select top 1 * from table order by indexID desc
其它的前一条,第一条等等类似。
离线g_tree
只看该作者 2楼 发表于: 2010-11-23
还是建议使用标准模型吧~~~~
离线lxbin2003

只看该作者 3楼 发表于: 2010-11-28
可能我没有说明初衷。我是要做一个通用工具,将数据备份到本地。

我希望它有一个接口,能够传出一个类似数据库句柄的东东,再有一个标准接口给程序员自己管理取多少数据,不需要QT封装缓存全部数据,这样就给程序员提供了更大的灵活性。
它现有的封装包做了几乎全部的事情,结果也是丧失了灵活性,迫使程序员不得不按照它的路子往下走,一般情况下没问题,但数据量大了,问题就出来了。
象我这个数据导出的问题,其实不需要它把数据全部缓存起来,要是有这样一个接口,然后通过内存映射文件,直接写到文件中去,效率和速度都比较理想,也不占用多少内存,海量数据处理也不是问题,不是吗?
当然这个也可以我自己去实现,但自己实现和QT将来的版本有可能会有冲突,而且要对每种数据库接口要做修改,工作量比较大。
我觉得这是一个缺陷,并不是它现有设计上有缺陷,而是觉得它易用性有了,却缺乏最大限度的灵活性。
谢谢大家!

to samsam598 :
数据分页是个办法,但这不是一个通用办法,因为我在做一个通用工具,不局限于某种数据库,因此,分页困难非常大,还不如直接实现一个低级点的,灵活性高点的数据接口。
离线huzhiwen28

只看该作者 4楼 发表于: 2010-11-29
我觉得直接使用sql的API接口就可以了,干嘛要使用model?
http://blog.sina.com.cn/tonyhuzhiwen
https://github.com/huzhiwen28/
专注于工业嵌入设备开发
离线lxbin2003

只看该作者 5楼 发表于: 2010-11-29
引用第4楼huzhiwen28于2010-11-29 14:20发表的  :
我觉得直接使用sql的API接口就可以了,干嘛要使用model?


准备做一个通用的,不限定于某种数据库,所以,直接用SQL 的 API太累人了,似乎是把QSql重写了。 偷懒嘛。当然,不用model,用QSqlQuery也行,只不过,两者一样,底层缓存多了会crash。
大家多给点意见啦。:)
离线foxyz

只看该作者 6楼 发表于: 2010-12-01
QSqlTableModel本身就是一个model, 我好像从来没用过这个model来做数据库操作的。
楼主, 数据库操作跟Qt没啥关系。50G的数据量我都操作过, 啥问题没有。不知道你为啥用这个model来操作。说到底,Qt 对数据库的操作还是使用了具体的数据库driver. 我曾经做过一个ETL工具。每天的数据量都是10G以上的(交易所行情数据)也没出过啥问题
离线lxbin2003

只看该作者 7楼 发表于: 2010-12-01
引用第6楼foxyz于2010-12-01 12:13发表的  :
QSqlTableModel本身就是一个model, 我好像从来没用过这个model来做数据库操作的。
楼主, 数据库操作跟Qt没啥关系。50G的数据量我都操作过, 啥问题没有。不知道你为啥用这个model来操作。说到底,Qt 对数据库的操作还是使用了具体的数据库driver. 我曾经做过一个ETL工具。每天的数据量都是10G以上的(交易所行情数据)也没出过啥问题


可能你是固定在某个数据库上吧,比如oracle,比如sql server.象这样固定在某个数据库上,可以直接用API编程,比如OCI,或者DB-lib,效率比较高,稳定性也好。
用QT,它有一个好处就是不管你后台使用什么数据库,都有一致的使用接口。用QSqlDatabase,QSqlQuery就可以连接数据库,查询数据库,而不必使用OCI之类的API。
本人经常使用不同的数据库,所以觉得用QT写一个通用的东西,比较省事。否则每个数据库都要写一个工具,功能一样,代码不一样。
不知道这样解释,你是否能理解我的意思。
离线huzhiwen28

只看该作者 8楼 发表于: 2010-12-02
楼主可以看看QT数据库封装代码,看看是否有什么办法,不要将数据缓存在对象中,实际使用的时候再真正读进来。
http://blog.sina.com.cn/tonyhuzhiwen
https://github.com/huzhiwen28/
专注于工业嵌入设备开发
快速回复
限100 字节
 
上一个 下一个