2010-01-04 177 views
1

我已经用Identity Map模式实现了Data Mapper模式。简而言之:当我想要从数据库中获得2000个对象时,映射器会根据包含对已创建对象的引用的哈希映射来检查结果集。如果一个id已经在哈希映射中,那么旧对象将被添加到返回数组中。否则,会创建一个新对象并将其添加到返回数组中。返回数组将包含2000个对象。在这种情况下我应该采取哪种方法?

注意:这个数字是理论上的!该平台可能会很频繁地出现,所以这可能每分钟甚至几秒发生多次。

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

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

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

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

回答

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 

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

相关问题