2

好的,这是专业人士的:

几年来,我一直在研究我自己的 PHP ORM/ActiveRecord 实现,我将其命名为Pork.dbObject。

它大致基于几年前我们都看过的“在 5 分钟内用 Rails 制作自己的网站”电影。您可以执行以下操作:

$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 没有结果。

所有这一切都在几十个站点和后端完美运行,但现在我的同事正在使用它来创建一个巨大的日志解析器,这里开始出现内存使用问题..

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

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

现在我们来解决我真正的问题:我可以毫无问题地这样做吗?数据库是否能够处理多个打开的结果集,并将它们混合并在内存中保存一段时间?

例如,获取 20 个对象,循环它们,让这 20 个对象中的每一个获取另外 5 个对象,然后它们也获取另外 3 个对象。这将创建一个循环,其中许多不同的结果句柄将保存在内存中。

我知道我无法序列化这些对象之一,但我能否在 PHP5 中毫无问题地实现这一点,或者数据库接口会给我带来问题?

4

1 回答 1

2

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

对于 MySQL,您需要确保使用缓冲查询。在 PDO 中,您可以这样设置:

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

这意味着所有数据都将发送到客户端(与在 PHP 中获取所有数据不同)。

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

正常mysql_query()使用缓冲查询,因此可以处理多个结果集。

于 2009-02-10T09:05:17.510 回答