2

私はPHP(Kohana)でオブジェクト指向のMVCフレームワークを使用しており、いくつかの手法を組み合わせて作業を行っています。問題は、ページごとにたくさんのクエリを呼び出さずに物事をきれいに保つ方法がわからないことです。

私の例を説明するために、私はサイトのようなスタックオーバーフローを設計していると想像します。

質問用のモデルクラス(question_model)と質問ファインダー用のモデルクラス(question_finder_model)があります。

question_modelには主に、質問データ、回答オブジェクトの配列、およびいくつかのファクトリメソッドを格納するための変数が含まれています。何かのようなもの:

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

質問ファインダーには、question_modelオブジェクトの配列と質問IDの配列が含まれています。IDの配列は、クラス内の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
     }
}

したがって、このメソッドをすべてのモデルに使用します。たとえば、ユーザーモデルには質問オブジェクトの配列が含まれます。

問題は、処理が非常に難しくなっていることです。たとえば、私の質問には多くの回答が含まれており、各回答には多くのコメントが含まれている可能性があります。いくつかのクエリを実行せずに、これらすべてのオブジェクトにデータを入力するにはどうすればよいですか。つまり、簡単な方法は、質問オブジェクトの配列を反復処理し、そのオブジェクトの回答情報を取得する質問クラス内に格納されている関数を呼び出すことです。しかし、その場合、ページごとに数十または数百のクエリを呼び出すことになります。

問題を明確にするのは非常に難しいので、これがすべて少しかすんでいる場合はお詫び申し上げます。perhpas私のパターン全体に欠陥があるので、どんな助けでもありがたいです。

4

3 に答える 3

3

ここで表現しているのは、単純な ORMappers の最も一般的な問題の 1 つです。いくつかのクエリを生成します。

ここで問題の正確な説明を読むことができます: ORMs Done right: (DBA Gripe #3: 隠された高価なアクション)

基本的に問題は、次のようなものに対していくつかのクエリが必要なことです。

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";
       }
    }
 }

}

それは本当に遅くなり、本当に速くなります。

必要なことは、適切な結合を使用して1 つのクエリですべての情報を取得することです。次に、オブジェクトにデータを入力します。

いくつかの記事で提案された実装を探してください: Class::ReluctantORM — 必須のプリフェッチ

最後に、すべてのケースを正しくしようとしてハングアップしないでください。リレーショナル モデルとオブジェクト モデルの「インピーダンスの不一致」は解決された問題ではありません。したがって、自分で完全に解決しようとしないでください。結局、オブジェクト リレーショナル マッピングはコンピュータ サイエンスのベトナムです

于 2009-09-26T04:54:29.197 に答える
1

SQL よりも PHP とはあまり関係がありません。

コメントを含む質問の回答のリストを取得するには、質問 ID ですべての回答を取得できます。次に、すべての回答 ID を配列に収集し、その配列に回答 ID を持つすべてのコメントをフェッチします。

それは3つのクエリです。コード内でどのコメントがどの回答に属しているかを判断するだけで済みます。回答 ID などでコメントを並べ替えると、より高速に処理できます。

また、memcached を使用して、ファイルなどにキャッシュすることもできます。これにより、処理速度が大幅に向上します。

もちろん、そのような構造からオブジェクトを構築することは、クエリごとよりもトリッキーになる可能性がありますが、それは実行する必要があることです。

于 2009-09-25T21:33:37.450 に答える
0

Jani Hartikainen はそれをかなりうまくまとめています。

OOP を学ぶと、すべてがオブジェクトのように見え始めます。

すべてをクラスとして宣言し、オブジェクトとして見ることができるのは事実ですが、そうする必要はありません。あなたの例では、個々の質問/回答/コメント オブジェクトを処理するよりも、大量のデータ操作と見なされる方がおそらく簡単です。

その角度から見れば、おそらくジャニ自身のような解決策を思いつくでしょう。

于 2009-09-25T21:56:23.347 に答える