Zend FR

Consultez la FAQ sur le ZF avant de poster une question

Vous n'êtes pas identifié.

#1 22-03-2011 16:33:48

justme
Membre
Date d'inscription: 22-03-2011
Messages: 10

Optimisation de requêtes, jointures

Bonjour,

Je débute dans l'utilisation de Zend, et souhaiterais avoir un complément d'information au sujet de l'utilisation des jointures.

J'ai besoin d'effectuer des requêtes sur plusieurs tables, appelons les
Table1(ID_table, login, nom, prenom,actif),
Table2(ID_table, ID_groupe,utilisation)
et
Table3(ID_groupe, nom_groupe),
Table2 étant liée à Table1 par ID_table et Table2 à Table3 par ID_Groupe.

Je souhaitais savoir quelle serait, selon vous, la façon la plus optimisée d'effectuer une requête comme celle-ci :

Code:

SELECT
            a.*,
            b.ID_GROUPE,
                        c.nom_groupe
        FROM 'Table1' a
        JOIN 'Table2' b USING(ID_table)
        JOIN 'Table3' c ON b.ID_GROUPE = c.ID_GROUPE
        WHERE a.LOGIN = '.$login.'
        AND a.ACTIF=1
        AND b.UTILISATION = abc';

Je souhaiterais que cela se fasse de préférence en une seule requête (ce à quoi je ne suis pas parvenue jusqu'ici), est-ce possible ?

De plus, j'ai l'impression, d'après mes recherches, qu'il faut forcément utiliser "en dur" le nom du modèle de la table à joindre, ce que j'aimerais limiter (en utilisant $_referenceMap ? Comment cela fonctionne-t-il vraiment ?).

Je vous remercie d'avance.

Dernière modification par justme (22-03-2011 16:41:17)

Hors ligne

 

#2 22-03-2011 17:15:31

_Fuse_
Membre
Lieu: Aquitaine
Date d'inscription: 10-07-2008
Messages: 92

Re: Optimisation de requêtes, jointures

Bonjour,

Je ne sais pas ce que tu entends par "le plus optimisé", mais voila ce que ça peut donner,

Code:

[lang=php]
$select = $db->select();
$select->from('Table1')    
               ->setIntegrityCheck(false)                                
               ->joinLeft('Table2','Table1.ID_table = Table2.ID_table')
               ->joinLeft('Table3','Table3.ID_Groupe = Table2.ID_Groupe ')
               ->where("Table1.LOGIN = $login")
                           ->where("Table1.ACTIF = 1")
                           ->where("Table2.UTILISATION = abc");

@+

Dernière modification par _Fuse_ (05-04-2011 09:15:07)

Hors ligne

 

#3 23-03-2011 09:19:27

justme
Membre
Date d'inscription: 22-03-2011
Messages: 10

Re: Optimisation de requêtes, jointures

Merci pour ta réponse.

Ma question sur l'optimisation portait sur deux points : le nombre de requêtes exécutées (j'en avais deux, mais j'ai pu comprendre que ma deuxième requête -findModel_Table2()- n'était finalement pas utile)

Mon deuxième point était : je souhaite éviter d'utiliser "en dur" le nom de ma table dans les différentes requêtes. Comment est-ce possible ? C'est ici qu'intervient $_referenceMap ?

Merci encore.

Hors ligne

 

#4 23-03-2011 10:11:16

_Fuse_
Membre
Lieu: Aquitaine
Date d'inscription: 10-07-2008
Messages: 92

Re: Optimisation de requêtes, jointures

Bonjour,


pour éviter de nommer le nom de ta table a chaque fois, je te conseil de regarder le quickstart de la doc :


Code:

[lang=php]
class Application_Model_GuestbookMapper
{
    protected $_dbTable;
 
    public function setDbTable($dbTable)
    {
        if (is_string($dbTable)) {
            $dbTable = new $dbTable();
        }
        if (!$dbTable instanceof Zend_Db_Table_Abstract) {
            throw new Exception('Invalid table data gateway provided');
        }
        $this->_dbTable = $dbTable;
        return $this;
    }
 
    public function getDbTable()
    {
        if (null === $this->_dbTable) {
            $this->setDbTable('Application_Model_DbTable_Guestbook');
        }
        return $this->_dbTable;
    }[/quote]
[quote]public function fetchAllExemple()
    {
        $users = $this->getDbTable();
        
        $select = $users->select(Zend_Db_Table::SELECT_WITH_FROM_PART)    
                        ->setIntegrityCheck(false)                                                
                          ->joinLeft...

pour le fameux $_referenceMap il s'agit de la variable renseignant les différentes liaisons de la table en question vers les autres tables

Code:

[lang=php]class Application_Model_DbTable_Guestbook extends Zend_Db_Table_Abstract
{
    protected $_name = 'guestbook'; //Le nom de la table
    protected $_primary = array('idxxx');    //la clef primaire
//le lien vers les autres tables
    protected $_referenceMap    = array(
        'Table2' => array(
            'columns'           => array('idxx'),
            'refTableClass'     => 'Application_Model_DbTable_Table2',
            'refColumns'        => array('idxx')
        ),
        'Table3' => array(
            'columns'           => array('idxx'),
            'refTableClass'     => 'Application_Model_DbTable_Table3',
            'refColumns'        => array('idxx'),
            
        )
    );
}

@+

Dernière modification par _Fuse_ (05-04-2011 09:17:31)

Hors ligne

 

#5 23-03-2011 10:24:58

justme
Membre
Date d'inscription: 22-03-2011
Messages: 10

Re: Optimisation de requêtes, jointures

Bonjour,

On est donc obligé de passer par un mapper pour ne pas nommer les tables à chaque fois ?

En ce qui concerne le $_referenceMap, faut-il vraiment y faire apparaitre Table3, qui n'a pas de lien direct avec Table1, comme dans ton exemple ? Ou c'était un exemple plus général peut être ?

Merci encore !

Hors ligne

 

#6 23-03-2011 10:49:36

_Fuse_
Membre
Lieu: Aquitaine
Date d'inscription: 10-07-2008
Messages: 92

Re: Optimisation de requêtes, jointures

Effectivement, pour Table3 c'était un exemple général wink

Hors ligne

 

#7 23-03-2011 11:12:51

justme
Membre
Date d'inscription: 22-03-2011
Messages: 10

Re: Optimisation de requêtes, jointures

Ok.

Et désolée d'insister là dessus, mais les mappers sont la seule façon de ne pas utiliser les noms des tables en dur dans le code ?

Hors ligne

 

#8 23-03-2011 11:34:26

_Fuse_
Membre
Lieu: Aquitaine
Date d'inscription: 10-07-2008
Messages: 92

Re: Optimisation de requêtes, jointures

Difficile de ne jamais nommer le nom de des tables dans le code wink

Perso je connais les deux solutions que je viens de donner, soit avec l'objet Zend_Db_Select ou avec l'objet Zend_Db_Table_Abstract.

Par contre je pense qu'il y a beaucoup d’intérêts à créer des mappers  comme expliqué dans le quickstart.

Dernière modification par _Fuse_ (23-03-2011 13:52:43)

Hors ligne

 

#9 23-03-2011 12:10:33

justme
Membre
Date d'inscription: 22-03-2011
Messages: 10

Re: Optimisation de requêtes, jointures

_Fuse_ a écrit:

Difficile de ne jamais nommer le nom de des tables dans le code wink

Certes, mais en inscrivant le nom de ma table en dur dans plusieurs scripts, si je veux changer son nom je vais devoir le changer à la main dans tous les scripts, ce qui est moins pratique que de le changer à un seul endroit (dans son modèle par exemple), et que ce changement soit répercuté sur les autres scripts utilisant cette table. D'où ma question sur la faisabilité de la chose.

(J'espère avoir été compréhensible sur ce coup ...)

Hors ligne

 

#10 23-03-2011 14:05:40

_Fuse_
Membre
Lieu: Aquitaine
Date d'inscription: 10-07-2008
Messages: 92

Re: Optimisation de requêtes, jointures

Autrement dit avec un mapper.


La fonction getDbTable() de la classe "Application_Model_MaClasseMapper" renvoi l'objet Zend_Db_Table_Abstract dans lequel est renseigné le nom de la table ($_name) donc une seul variable à modifier en cas de changement.

Application_Model_MaClasseMapper => contient les fonctions CRUD
Zend_Db_Table_Abstract => définit la table vers laquelle on veux avoir accès

Pas plus, pas mieux.

Hors ligne

 

#11 28-04-2011 14:12:25

Farid63
Nouveau membre
Date d'inscription: 20-04-2011
Messages: 6

Re: Optimisation de requêtes, jointures

Et pourquoi ne pas faire un constructeur pour initialiser $_dbTable puisque la classe Application_Model_GuestbookMapper utilisera toujours une instance de Application_Model_DbTable_Guestbook?



Code:

[lang=php]

class Application_Model_GuestbookMapper
{
    protected $_dbTable;
  
    public function __construct()
    {
        $this->_dbTable = new Application_Model_DbTable_Guestbook();
    }
...
}

A moins que ce Mapper peut instancier une autre Table Data Gateway ce qui serait bizarre étant donner qu'il s'appel GuesbookMapper, à moins que ça concerne les jointures et dans ce cas, je m'excuse de mon erreur.

smile

Hors ligne

 

Pied de page des forums

Propulsé par PunBB
© Copyright 2002–2005 Rickard Andersson
Traduction par punbb.fr

Graphisme réalisé par l'agence Rodolphe Eveilleau
Développement par Kitpages