2009-09-25 63 views
2

我在PHP(Kohana)中使用了一個面向對象的MVC框架,並且有種混合了一些技巧來完成一些東西。問題是我不知道如何保持清潔,而不必每頁調用大量的查詢。MVC面向對象技術 - 如何最小化查詢並保持靈活性?

爲了說明我的榜樣,我會想象我設計的網站一樣堆棧溢出:

我有一個問題(question_model)模型類,以及一個問題取景器(question_finder_model)。

question_model主要包含變量來存儲問題數據,答案對象數組和一些工廠方法。例如:

class question_model { 
    public $question_id,$question_title,$question_body,$answers = array();  
} 

問題finder容器包含一個question_model對象數組以及一個問題ID數組。 ids數組由類中的find方法填充並由其他方法使用。例如:

class question_finder_model { 
    private $question_ids = array(); 
    public $questions = array() ; // 

    function public find_questions() { 
     // executes some SQL to find a list of projects 
     // Create a new question_model object for each question and store in $questions 
     // for each of these questions store the id in $questions_ids 
    } 
    function public get_answer_info() { 
     // using all the question ids stored in $question_ids: 
     // find information about the answers 
    } 
} 

因此,我對我所有的模型都使用此方法,例如我的用戶模型將包含一組問題對象。

問題是,它變得越來越難處理,例如我的問題包含許多答案,每個答案可以包含許多評論等。我怎樣才能填充所有這些對象,而無需多次查詢。我的意思是簡單的方法是迭代通過我的問題對象數組,並調用存儲在問題類中的函數,該函數獲取該對象的答案信息。但接下來我會調用每頁10或100個查詢。

我很抱歉,因爲這個問題很難表達清楚,所有這一切都很朦朧。任何幫助,因爲perhpas我的整個模式是有缺陷的。

回答

3

你在這裏表達的是一個最常見的preoblems 與天真ORMappers。 生成多個查詢。

你可以在這裏閱讀你的問題的精確描述:ORMs Done right: (DBA Gripe #3: hidden expensive actions)

基本上,問題是,你需要幾個查詢這樣的事情:

foreach ($questions in $site) { 
foreach ($question as $questions) { 
    foreach ($answer in $question){ 
     foreach ($comment in $answer) { 
     echo "$site->title, $question->title, $answer->title, $comment->title"; 
     } 
    } 
} 

}

它變得非常緩慢,真的很快。

你需要做的是獲得所有的信息在之一查詢與正確的聯接。 然後填充你的對象。

尋找在一些文章建議的落實:類:: ReluctantORM - 強制預取

最後不要掛斷試圖讓每一個案件的權利。關係模型和對象模型「阻抗不匹配」不是一個解決的問題。所以不要試圖自己解決它。畢竟Object-Relational Mapping is the Vietnam of Computer Science

+0

「最後不要掛機試圖讓每一個案件都正確。」 < - 這是很好的建議。 – johnny 2014-08-26 18:40:52

1

對於PHP而言,它並沒有太多與SQL相關的東西。

要獲取問題答案列表(包括評論),您可以通過問題ID獲取所有答案。然後,將所有答案ID收集到數組中,並獲取所有在該數組中具有答案ID的註釋。

這是三個查詢。你只需要計算出哪個評論屬於代碼中的哪個答案 - 如果按answer ID對評論進行排序,則可以更快地進行評論,等等。

你也可以緩存memcached,文件或其他的東西,這應該可以很好地加快速度。

當然,從這樣的結構構建對象可能會比每查詢更復雜,但這只是您需要做的事情。

0

Jani Hartikainen總結得非常好,我想提一些其他的東西。

當你瞭解到OOP時, 一切看起來像一個 對象。

雖然所有事情都可以被聲明爲一個類並且被視爲一個對象,但事實並非如此。在你的例子中,它可能更容易被視爲一個海量數據操作,而不是處理單個問題/答案/評論對象。

一旦你從這個角度來看它,你可能會想出像賈尼這樣的解決方案。