2009-09-25 4 views
2

J'utilise un framework MVC orienté objected en PHP (Kohana) et j'ai en quelque sorte mélangé quelques techniques pour faire des choses. Le problème est que je ne suis pas sûr de savoir comment garder les choses propres sans appeler beaucoup et beaucoup de requêtes par page.MVC Object Oriented Techniques - Comment minimiser les requêtes et maintenir la flexibilité?

Pour illustrer mon exemple, je vais imaginer que je suis la conception d'un débordement de pile comme site:

Je classe de modèle pour une question (question_model) ainsi qu'un pour finder question (question_finder_model). Question_model contient principalement des variables pour stocker les données de question, des tableaux d'objets de réponse et quelques méthodes de fabrication. Quelque chose comme:

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

Les conteneurs finder question un tableau de question_model objets ainsi qu'un tableau de ids question. Le tableau d'identifiants est rempli par les méthodes find de la classe et utilisé par d'autres méthodes. Quelque chose comme:

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

J'utiliser cette méthode pour tous mes modèles, par exemple mon modèle d'utilisateur contiendra un tableau d'objets de questions. Le problème est qu'il devient assez difficile à gérer, par exemple ma question contient de nombreuses réponses et chaque réponse peut contenir de nombreux commentaires et ainsi de suite. Comment puis-je remplir tous ces objets sans avoir plusieurs requêtes. Je veux dire que la méthode la plus simple serait de parcourir simplement mon tableau d'objets questions et d'appeler une fonction stockée dans la classe de questions qui obtient les informations de réponses pour cet objet. Mais alors j'appellerais 10 ou 100 de requêtes par page. Je m'excuse si tout cela est brouillé car le problème est assez difficile à articuler. Toute aide est appréciée parce que perhpas tout mon modèle est défectueux.

Répondre

3

Ce que vous exprimez ici est l'un des préoblèmes les plus communs avec des ORMappers naïfs. Génération de plusieurs requêtes.

Vous pouvez lire la description précise de votre problème: ORMs Done right: (DBA Gripe #3: hidden expensive actions)

Fondamentalement, le problème est que vous devez plusieurs requêtes pour quelque chose comme ceci:

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

}

Cela devient vraiment lent , très rapide.

Ce que vous devez faire est d'obtenir toutes les informations dans une requête avec les jointures appropriées. Puis peupler vos objets.

Recherchez la mise en oeuvre suggérée dans le quelque article: Class :: ReluctantORM - préchargement obligatoire

Enfin, ne soyez pas raccrochage essayer d'obtenir tous les cas à droite. Le modèle relationnel et le modèle d'objet "inadéquation d'impédance" ne sont pas un problème résolu. Alors n'essayez pas de le résoudre vous-même parfaitement. Après tout Object-Relational Mapping is the Vietnam of Computer Science

+0

"Enfin, ne vous laissez pas raccrocher en essayant d'obtenir tous les cas." <- C'est un bon conseil. – johnny

1

Il n'a pas vraiment beaucoup à faire avec PHP que SQL.

Pour obtenir une liste de réponses à une question, y compris des commentaires, vous pouvez aller chercher toutes les réponses par numéro de question. Ensuite, collectez tous les identifiants de réponse dans un tableau et récupérez tous les commentaires qui ont un identifiant de réponse dans ce tableau.

Voilà trois requêtes. Vous devez juste déterminer quel commentaire appartient à quelle réponse dans le code - ce qui peut être fait plus rapidement si vous triez les commentaires par id de réponse, et ainsi de suite.

Vous pouvez également mettre en cache des éléments avec memcached, des fichiers ou autres, ce qui devrait accélérer les choses.

Bien sûr, la construction des objets à partir de telles structures peut être plus compliquée que la simple requête, mais c'est quelque chose que vous devrez faire.

0

Jani Hartikainen a très bien résumé cela, j'aimerais mentionner autre chose.

Lorsque vous avez appris POO, tout commence à ressembler à un objet .

S'il est vrai que tout peut être déclaré comme une classe et vu comme un objet, vous n'avez pas à le faire. Dans votre exemple, il est probablement plus facile d'être vu comme une manipulation de données de masse plutôt que de traiter des objets de questions/réponses/commentaires individuels.Une fois que vous l'aurez vu sous cet angle, vous aurez probablement des solutions comme Jani vous-même.

Questions connexes