2010-01-04 132 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 

所以,是的。我想這是一個基準問題,並取決於你的具體情況。

相關問題