2009-02-10 82 views
2

好,这里是一个亲的:ORM查询结果:比如数组vs结果句柄包裹在Iterator接口

对于几年了,我一直都在我自己的PHP ORM/ActiveRecord的实现,我命名Pork.dbObject.

它松耦合基于“让自己的网站有5分钟的轨道”的电影,我们都在几年前看到的。你可以做这样的事情:

$clients = dbObject::Search("Client", array("ID > 500")); 

$client = new Client(218); // fetch row with id 218 from client table 

$projects = $client->Find('Project'); 

这会从数据库中获取一个或多个行,将它们包装在一个DBOBJECT和一个返回它们数组,或返回false没有结果。

所有这一切已经在数十个网站和后端的工作完美,但现在我的同事正在使用它创造了巨大的LOGPARSER并在这里开始了内存使用的问题..

他跑可以返回在查询20.000行,甚至更多,这当然不是一件很好的事情,一次全部包装到一个对象包装中,并作为单个数组返回。

显而易见的解决办法是将返回实现Iterator接口而不是数组的对象。它不应该立即从结果集中获取所有记录,而只需为生成的数据库查询保存结果资源,并在遍历对象时使用mysql_fetch_ *,就像它是一个数组一样。

现在,我们得到我真正的问题: 我可以,没有任何问题,只是这样做?数据库能够处理多个打开的结果集,并将它们混合并保存在内存中一段时间​​?

例如,取20个对象,环它们,让每一个的这些20取5个他人,至极反过来也它们取3个其他。这将创建一个循环,将许多不同的结果句柄保存在内存中。

我知道我不能序列化这些对象之一,但我将能够实现这一点没有在PHP5任何问题,或将数据库接口给我的问题?

回答

2

这取决于您正在使用的数据库和数据库配置。

对于MySQL,您需要确保使用缓冲查询。在PDO将其设置是这样的:

$myPdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true); 

这意味着所有的数据将被发送到客户端(不一样获取这一切在PHP)。

另一种(可能更糟糕的)替代方法是,只要检测到结果集仍处于打开状态时运行的查询,就会打开一个新的数据库连接。

正常mysql_query()使用缓冲查询,以便将与多个结果集的工作。

+0

谢谢,这正是我要找的。我正在重写所有内容以便现在使用PDO。 – SchizoDuckie 2009-02-11 08:38:30