Publicité
+ Répondre à la discussion
Affichage des résultats 1 à 3 sur 3
  1. #1
    Membre actif
    Inscrit en
    avril 2007
    Messages
    435
    Détails du profil
    Informations personnelles :
    Âge : 27

    Informations forums :
    Inscription : avril 2007
    Messages : 435
    Points : 187
    Points
    187

    Par défaut Jointures de table dans couches data et business

    Bonjour,

    Je démarre un nouveau projet que je souhaite developper en couche.
    La technologie est PHP5 et MySQL via PDO, mais j'utiliserai une sorte de pseudo language dans ce post.
    Mon prototype est en train de voir le jour, l'implémenation est la suivante :
    1. Une couche d'accès aux données (data)
    2. Une couche service (business)
    3. Une couche présentation


    Mon questionnement vient des couches 1 et 2.
    En effet, dans ma couche 1, j'ai un objet par table SQL qui se charge de faire des opérations "atomiques" :

    Code :
    1
    2
    3
    getAll() => Retourne toutes les lignes
    getById( id ) => Retourne la ligne "WHERE id = id"
    getByDate( dateInf, dateSup ) => Retourne les dates "WHERE date BETWEEN dateInf, dateSup"
    La couche 2 quant à elle est là pour ajouter l'intelligence et utiliser la couche 1.
    Par exemple, j'ai un service contenant la méthode suivante :

    Code :
    1
    2
    3
    4
    5
    6
    7
    getLinesOfTheWeek() { // Retourne toutes les lignes de la semaine en cours
    
    	thisMonday = computeMonday( now.getDate() ); // Calcule la date SQL du lundi en cours
    	thisSunday = computeSunday( now.getDate() ); // Idem pour dimanche
    
    	return LinesDataObject.getByDate( thisMonday, thisSunday );
    }
    Le problème vient des jointures de table.
    Dans cette architecture, je suis obligé de boucle sur les résultats d'un premier objet data avant d'aller tapper dans une autre table.
    Par exemple, je prends des lignes d'une table A et je veux récupérer le libellé associé à l'id d'une colonne dans une table B :

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    myServiceMethod() {
    
    	// Récupère un tableau results avec toute la table
    	results = A.getAll();
    	
    	foreach( results as result ) {
    
    		// Recherche dans la table étrangère correspondant à un id de la ligne de A
    		bLine = B.getById( result.labelId )
    		
    		// Enrichie le tableau des résultats de A avec le libellé récupéré dans B
    		result['labelId'] = bLine['label'];
    
    	}
    	
    	// Contient désormais la clé 'labelId' de A et 'label' de B
    	return results;
    }
    Ce problème se résouds évidemment très facilement avec une jointure entre A et B sur "A.labelId = B.id".
    Cependant je ne voie pas comment intégrer cette requête dans cette architecture.
    Dois-je la mettre dans la table A ? Dans la table B ? Cela ne remet-il pas en question l'architecture elle-même ?
    Dans ce cas simple, je pourrais mettre la requête avec jointure dans la table A car ce sont à la base des lignes de A que l'on veut enrichir, mais il y a des cas de multi-jointure où la question sera très probablement plus épineuse.

    Merci pour vos indications.

  2. #2
    Membre Expert
    Homme Profil pro Jean
    Ingénieur développement logiciels
    Inscrit en
    mai 2011
    Messages
    289
    Détails du profil
    Informations personnelles :
    Nom : Homme Jean
    Âge : 33
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Finance

    Informations forums :
    Inscription : mai 2011
    Messages : 289
    Points : 1 045
    Points
    1 045

    Par défaut

    Citation Envoyé par FabaCoeur Voir le message
    Mon prototype est en train de voir le jour, l'implémenation est la suivante :
    1. Une couche d'accès aux données (data)
    2. Une couche service (business)
    3. Une couche présentation



    Le problème vient des jointures de table.
    Dans cette architecture, je suis obligé de boucle sur les résultats d'un premier objet data avant d'aller tapper dans une autre table.
    Par exemple, je prends des lignes d'une table A et je veux récupérer le libellé associé à l'id d'une colonne dans une table B :

    Ce problème se résouds évidemment très facilement avec une jointure entre A et B sur "A.labelId = B.id".
    Cependant je ne voie pas comment intégrer cette requête dans cette architecture.
    J'ai bien envie de te dire d'adapter la sacro sainte architecture trois tiers à ton projet.

    3 tiers ne veut pas dire prendre un objet par table et faire des requêtes simples dessus. Tu peux avoir des requêtes élaborées qui utilisent des jointures complexes dans la couche données. Les seuls impératifs, c'est:
    • que l'API que tu fournis à ta couche métier ne change pas si tu modifies la façon dont tu codes tes données.
    • que les objets utilisés par la couche métier restent eux aussi stables avec le temps.

    En particulier, si tu passes à une BD XML ou que sais je, rien ne doit bouger dans la couche métier.

    Par conséquent, si tu as besoin de jointures, fais au plus simple.
    Il vaut mieux du code simple et lisible dans ta couche données qu'un algo de malade dans ta couche métier. Ceci d'abord pour des raisons de performance, mais ensuite pour débugger ou faire évoluer ton code

  3. #3
    Membre actif
    Inscrit en
    avril 2007
    Messages
    435
    Détails du profil
    Informations personnelles :
    Âge : 27

    Informations forums :
    Inscription : avril 2007
    Messages : 435
    Points : 187
    Points
    187

    Par défaut

    Bonjour,

    Je viens de comprendre que le problème se situe au niveau de la contrainte que je me suis donné pour mes objets données, d'avoir pris table par table. En déclarant des objets plus globaux ça devrait simplifier le code au niveau de la couche métier sans pour autant rentrer dans une implémentation compliquée au niveau donnée.

    Merci pour ces réponses, que je n'attendais plus trop

+ Répondre à la discussion
Cette discussion est résolue.

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •