在这种情况下我应该采取哪种方法?

时间:2010-01-04 16:57:13

标签: php

我已经使用Identity Map模式实现了Data Mapper模式。简而言之:当我想从数据库中获取2000个对象时,映射器会根据包含对已创建对象的引用的哈希映射来检查结果集。如果id已经在哈希映射中,则旧对象将添加到返回数组中。否则,将创建一个新对象并将其添加到返回数组中。返回数组将包含2000个对象。

注意:这个数字是理论上的!平台可能是高频率的,因此这可能每分钟或甚至第二次发生多次。

问题:哪个选项更好,为什么?

A)从数据库中检索所有2000个对象。迭代记录集(2000行),并根据身份映射检查每个id。如果它在那里,将标识映射的引用对象添加到对象数组。如果没有,请创建一个新对象并将其添加到结果数组中。

B)创建一个(可能是巨大的)sql查询,它排除身份映射中的所有id。获取仅包含新对象数据的记录集。创建新对象而不检查每行的标识映射。包含许多字符串连接操作来构建查询,但可以保存一大堆哈希映射查找。

你会采取哪种方法? (是的,我知道,我应该实现两个版本并进行性能测试,但也许有人可以从实际经验中回答这个问题)

1 个答案:

答案 0 :(得分:0)

我会选择B。

我认为这不会带来复杂的字符串连接。假设您的ID是普通数组键,您可以这样做:

$ids   = implode(',', array_keys($hashmap));
$query = sprintf('SELECT * from records WHERE id NOT IN (%s)', $ids);

您可能希望为查询字符串添加一些清理。

如果您已经将SplObjectStorage用于散列图,则必须迭代地图以从存储的对象中获取ID。根据已经存在的项目数量和获取的数量,您可能更适合使用A或B.这取决于。但是使用SplObjectStorage,您不必费心附加已经存在的对象,因为这已经在本地处理,例如。

$map = new SplObjectStorage;
$one = new StdObject;
$map->attach($one);
$map->attach($one);
$map->count(); // returns 1

所以,是的。我想这是一个基准测试问题,取决于您的具体情况。

相关问题