Publicité
+ Répondre à la discussion
Affichage des résultats 1 à 9 sur 9
  1. #1
    Futur Membre du Club
    Inscrit en
    février 2003
    Messages
    38
    Détails du profil
    Informations forums :
    Inscription : février 2003
    Messages : 38
    Points : 17
    Points
    17

    Par défaut Réutilisation de sous-requête

    Bonjour à tous,

    Je reviens vers vous avec une nouvelle question. Tout d'abord, voilà une idée de la structure de ma base :

    J'ai une table principale, A, qui contient dans chaque enregistrement :

    Les id_b, id_c, id_d contiennent des id correspondant aux table B, C et D, mais ne sont pas déclarées comme clé étrangères car le nom des tables B, C et D peuvent changer (en gros, j'indique un id qui existe dans une autre table, et je récupère le nom de cette table autre part dans la bdd).

    La sous-requête que je veux réutiliser plusieurs fois me fournis un ensemble d'id de la table A (environ 400 ou 500 id en général sur un total important, j'aurais a terme sûrement un million d'enregistrement dans cette table). Je dois ensuite faire plusieurs requêtes pour récupérer les infos correspondantes dans B, puis dans C, puis dans D (qui sont chacune liées à d'autres tables, donc je préfère faire les requêtes séparées pour limiter la taille des résultats).

    Pour info, je communique avec ma base via pqxx depuis un programme en C++, j'ai donc toute latitude pour traiter un résultat et le reformater pour une requête suivante.

    J'envisage plusieurs solutions, mais je n'ai aucune idée de leur efficacité respectives (et de la possibililté de les mettre en oeuvre).

    La première consiste a récupérer le résultat de la requetes des A.id, puis de mettre la liste dans un A.id IN {id_1, id_2, ...} dans les clauses WHERE de mes requêtes suivante, mais j'ai peur que ce soit très peu efficace au niveau du traitement des requêtes suivantes.

    Une autre solution serait de stocker temporairement la requête le temps de faire mes autres requêtes puis de la supprimer ensuite, cependant je ne sais pas si cela est possible avec postgre

    La dernière solution serait de refaire la requête à chaque fois, mais j'aimerai bien éviter ça, sauf si postgre a un mécanisme de stockage interne du résultat des dernières requêtes...

    Merci d'avance,
    Babcool

  2. #2
    Expert Confirmé Sénior
    Homme Profil pro
    Inscrit en
    mai 2002
    Messages
    3 075
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : mai 2002
    Messages : 3 075
    Points : 5 075
    Points
    5 075

    Par défaut

    Bonjour,

    M'est d'avis que vous avez un gros problème de conception de votre base.


    S'en suit des essais d'algo tout aussi moins performant les uns des autres pour arriver à servir votre besoin


    A la base ce problème est une simple requete avec des jointures, rien de plus.

  3. #3
    Futur Membre du Club
    Inscrit en
    février 2003
    Messages
    38
    Détails du profil
    Informations forums :
    Inscription : février 2003
    Messages : 38
    Points : 17
    Points
    17

    Par défaut

    Hum, jvais ajouter un peu plus de détails pour décrire ma situation dans ce cas.

    Cette base de donnée est utilisé par une bibliothèque d'algo génétique générique, pour laquelle j'ai une forte spécialisation en fonction du cas d'utilisation.

    Une partie des tables sont donc gérées par la bibliothèque (génomes, gènes standard, session de travail, etc...) et le reste dépend du contexte d'utilisation de l'algorithme génétique (du dessin de graphe pour l'instant).

    Ma requête de base correspond à avoir une liste d'évaluation de génomes, une évaluation de génome correspond à un génome, un context d'évaluation, un score, et un comportement. Le génome est quand à lui constitué d'un ensemble de gène.

    Premier point, les gènes d'un génome, le soucis au niveau de la gestion est que je ne connais pas à priori les types des gènes utilisés, et ils peuvent avoir des structure très différentes (le gène basique est un nom associé à un valeur, un gène plus évolué peut contenir un arbre, ou des choses comme ça).
    Donc pour décrire les gènes appartenant à un génome, j'utilise une table gene_genome (car relation n_n, un gè,e pouvant appartenir à plusieurs génomes) qui contient l'id du génome, l'id du gène et le type du gène. La table contenant le gène est indiqué par le type du gène.

    Je suis face à un problème similaire pour les tables contenant le comportement et le contexte d'une évaluation d'un génome. La table contenant ces infos dépend complètement du cas d'utilisation de l'algo génétique. J'ai donc une classe en C++ (l'Evaluator, qui permet de fournir un score à chaque génome) qui connait la table dans laquelle il faut aller chercher le contexte et le comportement.

    Je ne peux pas donc faire un simple jointure, surtout dans la mesure ou je peux avoir beaucoup de gène par génomes, et de même dans les comportement, j'ai quelques jointures 1_n, et certains champs qui contiennent pas mal de données texte que je ne souhaite pas dupliquer lorsque j’envoie un résultat de requête, car il sera déjà largement assez gros comme ça.

    Pour info, j'ai pour l'instant 6 gène par génomes, 7 valeurs par comportement et 4 par contexte (une valeur correspond à un enregistrement dans une table annexe) donc si je fait une jointure basique, pour une requête de 400 génomes, j'aurais un résultat de 6*7*4*400 = 67200 lignes avec une redondance juste ignobles des données dans ce résultat. Je voudrais donc faire au moins 4 requêtes successives pour éviter cette démultiplication du nombre de résultat. Ces 4 requêtes se basant à chaque fois sur le résultat de la première fournissant les 400 évaluations sélectionnées.

    En continuant à chercher, je suis tombé sur les tables temporaires de postgre. Mais est ce ça vaut le coup de créer une table temporaire si je ne réutilise que 4 fois par la suite?

    Merci d'avance pour votre temps

  4. #4
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro Frédéric BROUARD
    Expert SGBDR & SQL
    Inscrit en
    mai 2002
    Messages
    13 559
    Détails du profil
    Informations personnelles :
    Nom : Homme Frédéric BROUARD
    Localisation : France

    Informations professionnelles :
    Activité : Expert SGBDR & SQL
    Secteur : Conseil

    Informations forums :
    Inscription : mai 2002
    Messages : 13 559
    Points : 30 053
    Points
    30 053

    Par défaut

    Citation Envoyé par Babcool Voir le message
    ...
    Donc pour décrire les gènes appartenant à un génome, j'utilise une table gene_genome (car relation n_n, un gè,e pouvant appartenir à plusieurs génomes) qui contient l'id du génome, l'id du gène et le type du gène. La table contenant le gène est indiqué par le type du gène.
    C'est là votre première erreur, car vous auriez dû modéliser un héritage...
    A me lire : http://sqlpro.developpez.com/cours/m...tion/heritage/

    Je suis face à un problème similaire pour les tables contenant le comportement et le contexte d'une évaluation d'un génome. La table contenant ces infos dépend complètement du cas d'utilisation de l'algo génétique. J'ai donc une classe en C++ (l'Evaluator, qui permet de fournir un score à chaque génome) qui connait la table dans laquelle il faut aller chercher le contexte et le comportement.
    Vous confondez conception objet et modèle relationnel. Rien à voir !

    Je ne peux pas donc faire un simple jointure...,
    Bien sur que si !


    ...surtout dans la mesure ou je peux avoir beaucoup de gène par génomes, et de même dans les comportement, j'ai quelques jointures 1_n, et certains champs qui contiennent pas mal de données texte que je ne souhaite pas dupliquer lorsque j’envoie un résultat de requête, car il sera déjà largement assez gros comme ça.
    Dans un SGBD relationnel, le modèle ne doit présenter aucune redondance !
    Pour info, j'ai pour l'instant 6 gène par génomes, 7 valeurs par comportement et 4 par contexte (une valeur correspond à un enregistrement dans une table annexe) donc si je fait une jointure basique, pour une requête de 400 génomes, j'aurais un résultat de 6*7*4*400 = 67200 lignes avec une redondance juste ignobles des données dans ce résultat. Je voudrais donc faire au moins 4 requêtes successives pour éviter cette démultiplication du nombre de résultat. Ces 4 requêtes se basant à chaque fois sur le résultat de la première fournissant les 400 évaluations sélectionnées.
    Je pense que vous n'avez pas compris grand chose à ce qu'est :
    1) une base relationnelle
    2) l'art de la modélisation des données

    En continuant à chercher, je suis tombé sur les tables temporaires de postgre. Mais est ce ça vaut le coup de créer une table temporaire si je ne réutilise que 4 fois par la suite?
    C'est une béquille quand on ne sait pas faire autrement !

    Merci d'avance pour votre temps
    Commencez par apprendre ce qu'est la modélisation conceptuelle et le respect des formes normales, à l'aide d'une notation comme MERIE ou UML.

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Blog SQL, SQL Server, modélisation données : http://blog.developpez.com/sqlpro
    http://www.sqlspot.com : modélisation, conseils, audit, optimisation, formation
    * * * * * Enseignant CNAM PACA - ISEN Toulon - CESI Aix en Provence * * * * *

  5. #5
    Futur Membre du Club
    Inscrit en
    février 2003
    Messages
    38
    Détails du profil
    Informations forums :
    Inscription : février 2003
    Messages : 38
    Points : 17
    Points
    17

    Par défaut

    Je pense m'être assez mal exprimé, car il me semble que ma situation a été mal comprise. Je vais donc passer par une image pour donner une idée plus précise de ma requête (j'espère que vous me pardonnerez le non respect des convention de présentation, j'ai fait ça en vistesse avec l'éditeur de requete graphique de pgadmin) (voir pièce jointe pour l'image)


    (les cases cochées et en rouge n'ont rien de particulier, je les ai cochée par erreur en réalisant la requête).


    Et quelques informations concernant mes contraintes d'utilisations. Ma base de donnée me sert a enregistrer des résultats de calculs, puis a sélectionner des échantillons de ces résultats pour les réinjecter dans les calculs suivants.
    J'ai tenté de faire une base la plus propre possible (en évitant il me semble toute redondance, je n'affirmerai pas que je suis en forme normale, mais je ne dois pas être très loin). Cependant, cette base va être utilisée avec une bibliothèque C++ fortement paramétrable et extensible. En particulier certaines tables de la base dépendent strictement du cas d'utilisation de la bibliothèque. Il ne m'est donc pas possible de connaitre dès à présent les requêtes qui seront faites sur cette base par la suite.
    Enfin, mon dernier point concerne la quantité de requête que je peux soumettre au serveur. J'ai une connexion internet de faible qualité et mes calculs sont réalisés à distance, je dois donc faire attention a limiter le nombre de requête que je réalise pour éviter de perdre trop de temps lors des soumissions/récupération des résultats. De même ayant une capacité d'uploads limité, je dois éviter d'avoir des résultats de requêtes de trop grande taille.

    Mon problème se situe au moment de la récupération des résultats, j'ai une requête A qui me fournit une liste de genome_evals.id. Je dois récupérer en un minimum de requête l'ensemble des infos concernant ces genome_evals, c'est à dire, les enregistrement dans vertex_context et dans graph_context associés, ainsi que les génomes et leurs genes.

    Mon idée consistait à récupérer dans un premier temps tous les id (vertex_context, vertex_metric, graph_context, metric_context, genome, genes) puis faire une requête par table avec la liste des id.
    Ma question est maintenant, est ce que je peux mémoriser facilement le résultat de la requête A temporairement sur le serveur, pour utiliser ce résultat pour récupérer les data, ou est ce qu'il vaut mieux que je passe par une énumération des id avec un opérateur IN (...,...,...)

    Si je fais une jointure basique entre tous mes champs, je vais avoir énormément de duplication des données dans le résultat qui sera renvoyé par la base à mon programme (car j'ai 6 gène par génomes, 4 ou 7 vertex_metric par vertex_context et 4 ou 7 metric_context par graph_context). Comme j'ai peur que ces redondances transparaisse directement dans la taille du résultat transmis par le réseau, je préfère l'éviter en faisant 5 ou 6 requêtes (une pour chaque table). Cependant, je ne peux pas me permettre de faire 5 ou 6 requête pour chaque génomes, donc je voudrais rappatrier tous les objets d'un même type en une seule requête.

    Concernant l'héritage pour les tables gènes et contexte/comportement, je l'avais envisagé dans un premier temps pour finalement l'abandonner car les seuls données que j'aurais pu factorisé auraient été les id (ce qui ne m'avancent pas plus, dans mon cas, au lieu d'avoir l'id comme clé principale, j'ai le couple nom/id).

    Merci d'avance,
    Babcool
    Images attachées Images attachées

  6. #6
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro Frédéric BROUARD
    Expert SGBDR & SQL
    Inscrit en
    mai 2002
    Messages
    13 559
    Détails du profil
    Informations personnelles :
    Nom : Homme Frédéric BROUARD
    Localisation : France

    Informations professionnelles :
    Activité : Expert SGBDR & SQL
    Secteur : Conseil

    Informations forums :
    Inscription : mai 2002
    Messages : 13 559
    Points : 30 053
    Points
    30 053

    Par défaut

    Excusez moi, mais c'est pas un modèle ça...
    1) toutes vos colonnes clef portent le même nom... Norme AFNOR "dans un système d'information, chaque information distincte doit porter un nom distinct".
    2) (corollaire) les clefs étrangères représentant le même information que la table de laquelle elle viennent doivent donc porter le même nom
    3) violation de la première forme normale : distrib1, distrib2, distrib3, distrib4... à quand le 5, le 6... ?
    4) des liens 1..1 sont généralement inutiles
    5) on ne conais pas la sémantique de vos liens
    ...

    bref, comme je le disais commencez par modéliser au niveau CONCEPTUEL sous forme Entité association (MERISE) ou classe association (UML).

    Offrez vous le bouquin de Soutou : http://www.amazon.fr/ULM-pour-bases-...0393027&sr=1-1
    Ou suivez notre cours à orsys :http://www.google.fr/url?sa=t&rct=j&...BuOOQL2cX8Rlmw

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Blog SQL, SQL Server, modélisation données : http://blog.developpez.com/sqlpro
    http://www.sqlspot.com : modélisation, conseils, audit, optimisation, formation
    * * * * * Enseignant CNAM PACA - ISEN Toulon - CESI Aix en Provence * * * * *

  7. #7
    Futur Membre du Club
    Inscrit en
    février 2003
    Messages
    38
    Détails du profil
    Informations forums :
    Inscription : février 2003
    Messages : 38
    Points : 17
    Points
    17

    Par défaut

    Et bien merci pour vos réponses, même si finalement je n'ai pas tellement avancé sur mon problème. J'imagine bien que mon modèle n'est pas idéal, ni conforme aux normes établies, mais je n'ai pas eu assez de temps à y consacrer pour me pencher la dessus et je n'en aurais pas beaucoup plus par la suite. C'est les joies de la thèse... Après, comme je n'aurais jamais de modèle parfait à vous présenter, je pense qu'il faudra que je trouve une autre manière de répondre à mes question, mais bon, le web est vaste

    Pour ce qui est des distrib, promis, les 5 et 6 n'arriveront jamais, (ils correspondent aux valeurs du 1er, 2e, 3e et 4e cinquièmes, vu que j'ai déjà la valeur max (ie 5e cinquième), et que le 6e cinquième ne risque pas d'apparaître de sitôt...).

  8. #8
    Expert Confirmé
    Profil pro
    Inscrit en
    octobre 2008
    Messages
    1 832
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : octobre 2008
    Messages : 1 832
    Points : 2 766
    Points
    2 766

    Par défaut

    Citation Envoyé par Babcool Voir le message
    En continuant à chercher, je suis tombé sur les tables temporaires de postgre. Mais est ce ça vaut le coup de créer une table temporaire si je ne réutilise que 4 fois par la suite?
    Oui, c'est fait pour ça.

  9. #9
    Futur Membre du Club
    Inscrit en
    février 2003
    Messages
    38
    Détails du profil
    Informations forums :
    Inscription : février 2003
    Messages : 38
    Points : 17
    Points
    17

    Par défaut

    Ok, dans ce cas, je vais partir la dessus. Je peux facilement déterminer quand je n'aurais plus besoin de cette requête, donc je clôturerais ma session à ce moment là.

    Merci bien

+ 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
  •