IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 SGBD Discussion :

Problème de conception ? "Boucle" de relations entre tables d'une BD


Sujet :

SGBD

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2015
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2015
    Messages : 7
    Points : 8
    Points
    8
    Par défaut Problème de conception ? "Boucle" de relations entre tables d'une BD
    Bonsoir à tous !

    Tout d'abord j'espère que mon post se situe dans la bonne catégorie ; j'ai hésité entre celle-ci et la partie "Schéma" donc si un modérateur passe par là et juge bon de déplacer ce sujet c'est avec plaisir.

    Pour un exercice je suis chargé de mettre en place une base de données assez simple concernant des points d'observation d'oiseaux. Je ne pensais pas rencontrer de problème mais tout débutant que je suis je me heurte à un souci inattendu (quoique prévisible à bien y penser). Voici d'abord les relations de ma BD à ce jour :

    Nom : BDoiseaux.png
Affichages : 3055
Taille : 18,7 Ko

    Quelques explications :
    - La table Tobs regroupe des informations sur les points d'observation des oiseaux : les coordonnées (Xobs et Yobs), le code INSEE de la commune d'observation (INSEEobs) et l'identifiant de la personne ayant réalisé l'observation (IDpers).
    - La table Tesp concerne les espèces observées avec leur nom vernaculaire (NomVer) et leur nom scientifique (NomSci). Entre ces deux tables une table Tinter car une observation peut concerner plusieurs espèces et vice-versa.
    - La table Tpers regroupe les informations sur les observateurs : leur nom et prénom et leur commune de résidence (INSEEres).
    - La table Tcom regroupe des informations sur les communes : le nom, l'air, les coordonnées de la mairie (Xmair et Ymair).
    - Les tables Tdpt et Tfam ne concerne pas mon problème à priori.

    Comme vous pouvez le voir il existe une sorte de "triangle relationnel" entre Tobs, Tcom et Tpers : l'observation a lieu dans une commune (relation Tobs-Tcom) par une personne (relation Tobs-Tpers) et chaque personne réside dans une commune (relation Tpers-Tcom). Cela pose des problèmes au moment des requêtes, par exemple si je veux avoir la liste des espèces observées, par quelle personne et la commune d'observation... puisqu'en demandant le nom de la commune je ne peux pas faire la distinction entre commune d'observation et commune de résidence. Je n'en obtiens donc que les observations faites par une personne dans la même commune que celle où il réside ce qui ne me convient pas vraiment.

    Je vois bien qu'il y a un souci dans la conception de ma base mais je ne parviens pas à mettre le doigt dessus tout en évitant une redondance d'informations : dois-je créer deux tables commune, une pour les communes d'observation et de résidence ? Mais dans ce cas elles contiendront les mêmes informations...

    J'avais supposé déplacer INSEEobs dans la table Tinter mais à priori j'aurai toujours le même problème.

    Voilà pour la situation générale. Il s'agit probablement d'un problème basique (c'est le cas de le dire) évident mais étant totalement débutant dans la mise en place de bases de données j'avoue ne pas m'en sortir et ne pas avoir le déclic. Quelqu'un pourra peut-être éclairer ma lanterne et pointer du doigt mes erreurs.

    En remerciant par avance ceux qui prendront de leur temps pour m'aider à démêler ma base... N'hésitez pas si je n'ai pas été assez clair et si vous avec besoin de plus d'informations !

    Bonne soirée à tous !

  2. #2
    Modérateur
    Avatar de sevyc64
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2007
    Messages
    10 193
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 193
    Points : 28 077
    Points
    28 077
    Par défaut
    Citation Envoyé par BModjo Voir le message
    Comme vous pouvez le voir il existe une sorte de "triangle relationnel" entre Tobs, Tcom et Tpers : l'observation a lieu dans une commune (relation Tobs-Tcom) par une personne (relation Tobs-Tpers) et chaque personne réside dans une commune (relation Tpers-Tcom). Cela pose des problèmes au moment des requêtes, par exemple si je veux avoir la liste des espèces observées, par quelle personne et la commune d'observation... puisqu'en demandant le nom de la commune je ne peux pas faire la distinction entre commune d'observation et commune de résidence. Je n'en obtiens donc que les observations faites par une personne dans la même commune que celle où il réside ce qui ne me convient pas vraiment.

    Je vois bien qu'il y a un souci dans la conception de ma base mais je ne parviens pas à mettre le doigt dessus tout en évitant une redondance d'informations : dois-je créer deux tables commune, une pour les communes d'observation et de résidence ? Mais dans ce cas elles contiendront les mêmes informations...
    Je en vois pas ici de "triangle relationnel". Tu en aurais un si tu avais la même info, par exemple ici, l'information Commune de la table personne faisant référence à la commune d'observation, info déjà présente dans la table observation.
    Hors ici, tes informations Communes sont 2 informations totalement différentes et indépendantes, sans lien entre-elles (à priori d'après tes explications en tout cas).

    Non pour moi, il n'y a pas de problème de conception ou de modélisation.

    Par contre, je présents bien un problème dans tes requêtes. Quelque chose me dit que tu dois faire des jointures implicites en laissant le SGBD décider lui-même de la liaison de tes jointures, le tout en ramenant la totalité des champs de chaque table. Quelque chose du style
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * FROM TObs, TPers, TCom
    Si, dans la plupart des cas, les SGBD se débrouillent pas mal dans ce genre de situation, des fois ça marche pas. La cause est leur tendance à vouloir faire le lien sur les champs communs des tables jointes.

    Il faudra faire (et je suis un prophète du il faut absolument faire, tout autre méthode est le mal absolu) des jointures explicites en précisant bien manuellement les liens souhaités.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT * FROM Tobs O
    INNER JOIN TPers P ON O.IDPers=P.IDpers
    INNER JOIN TCom C ON O.INSEEobs=C.INSEE
    --- Sevyc64 ---

    Parce que le partage est notre force, la connaissance sera notre victoire

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2015
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2015
    Messages : 7
    Points : 8
    Points
    8
    Par défaut
    Bonjour, et merci pour votre réponse.

    Effectivement j'utilise un assistant pour la création de mes requêtes (je travaille sous Access) ; je dois avouer que la méthode me semblait moins sûre que de rédiger les requêtes directement en SQL mais sans pour autant penser qu'il existerait une grande différence (pour la simple et bonne raison que jusque là je n'avais pas rencontré de souci sur mes autres bases de données).

    J'ai cependant une autre question concernant le code que vous proposez :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT * FROM Tobs O
    INNER JOIN TPers P ON O.IDPers=P.IDpers
    INNER JOIN TCom C ON O.INSEEobs=C.INSEE
    Dans ce cas la jointure est faite entre Tobs et Tpers (donc entre l'observation et l'observateur) et entre Tobs et Tcom (donc entre l'observation et la commune d'observation), cependant dans ce cas présent la jointure entre Tpers et Tcom n'est pas faite (entre l'observateur et sa commune de résidence). Dois-je donc rajouter des lignes du type
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT * FROM Tobs O
    INNER JOIN TPers P ON O.IDPers=P.IDpers
    INNER JOIN TCom C ON O.INSEEobs=C.INSEE,
    Tpers P INNER JOIN Tcom C ON P.INSEE=C.INSEE
    afin de réaliser cette jointure ? Et dans ce cas est-ce qu'on n'en revient pas au même problème qu'au début ?

    NB. Evidemment j'ai un peu bidouillé ma base de données et mes requêtes avant de poster cette réponse... et évidemment la syntaxe est mauvaise.

    Mettons que je souhaite réaliser une requête me donnant toutes les observations (avec leur IDobs), la personne ayant réalisé l'observation, ainsi que le nom de la commune d'observation ET celui de la commune de résidence de l'observateur. J'imagine que je devrai créer deux nouveaux champs dans ma requête pour ces deux communes qui peuvent différer l'une de l'autre (l'observateur ne réalisant pas forcément l'observation dans sa commune de résidence). Comment expliciter en SQL qu'un champ ira chercher le nom de la commune d'observation à partir de l'INSEE de Tobs (pour obtenir le nom de la commune d'observation) et d'autre part à partir de l'INSEE de Tpers (pour obtenir le nom de la commune de résidence de l'observateur) ? Je dois avouer avoir un peu de mal à visualiser comment imbriquer tout ça en SQL.

    Je vois sur ce forum que plusieurs personnes ont déjà eu des soucis avec l'inclusion de plusieurs INNER JOIN dans une requête, je potasse ça en ce moment.

  4. #4
    Modérateur
    Avatar de sevyc64
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2007
    Messages
    10 193
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 193
    Points : 28 077
    Points
    28 077
    Par défaut
    Citation Envoyé par BModjo Voir le message
    Dans ce cas la jointure est faite entre Tobs et Tpers (donc entre l'observation et l'observateur) et entre Tobs et Tcom (donc entre l'observation et la commune d'observation), cependant dans ce cas présent la jointure entre Tpers et Tcom n'est pas faite (entre l'observateur et sa commune de résidence). Dois-je donc rajouter des lignes du type
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT * FROM Tobs O
    INNER JOIN TPers P ON O.IDPers=P.IDpers
    INNER JOIN TCom C ON O.INSEEobs=C.INSEE,
    Tpers P INNER JOIN Tcom C ON P.INSEE=C.INSEE
    afin de réaliser cette jointure ? Et dans ce cas est-ce qu'on n'en revient pas au même problème qu'au début ?
    Tout à fait, dans le code que j'ai donné, seule la commune d'observation est retournée. Si tu veux en plus la commune de l'observateur, il faut effectivement rajouter une autre jointure, et ton code était presque bon.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT * FROM Tobs O
    INNER JOIN TPers P ON O.IDPers=P.IDpers
    INNER JOIN TCom C ON O.INSEEobs=C.INSEE
    INNER JOIN Tcom CP ON P.INSEE=CP.INSEE
    Tu constatera, avec ce code qui doit fonctionner, que sont retournés l'ensemble des champs de chaque table, que donc les champs de la table commune sont retournés 2 fois mais avec des données différentes puisque ce n'est pas le même lien.
    Tu constatera d'ailleurs que le second jeu de champs de la table commune ont été automatiquement renommés pour ne pas les confondre avec le premier jeu.
    Tout cela est dû au SELECT * qui retourne tout.

    Maintenant tu peux indiqué dans le select quels champs retourner, mais comment différencier les champs des 2 jeu de la table commune ?
    Tu remarqueras que dans les jointures j'ai donné des petits alias aux tables jointes (et je te conseille vivement de le faire systématiquement) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     Tobs O
    TPers P 
    TCom C 
    Tcom CP
    Ce n'est pas simplement pour faciliter l'écriture de la jointure, mais aussi pour clarifier la clause SELECT.
    En effet, si tu écrits SELECT NomCom ..., le SGBD, dans son jeu de résultat aura 2 champs NomCom, il ne saura pas lequel prendre. Au mieux tu auras un message d'erreur, au pire il en choisira arbitrairement un, et, loi de Murphy oblige, très probablement pas le bon.

    Maintenant si tu lui écrits SELECT CP.NomCom ..., il n'y a plus d’ambiguïté, le SGBD sait que parmi les 2 champs qu'il a à disposition, c'est celui qui vient de la jointure avec personne qu'il doit retourner.
    (et, là encore, je te conseille vivement de toujours préciser, dans la clause SELECT, de quelle table/alias retourner le champs désiré, même lorsqu'il n'y a pas d’ambiguïté. Si jamais un jour tu rajoute une jointure créant cette ambiguïté, tu sera content de ne pas avoir à reprendre la totalité de la requete pour rajouter les alias manquants)



    Autre point sur les alias, si tu écrits ceci : SELECT C.NomCom, CP.NomCom... tu auras dans ton jeu de résultat une colonne NomCom et une colonne probablement nommé NomCom_1. Pas très parlant.
    Là aussi tu peux utiliser des alias : SELECT C.NomCom AS CommuneObs, CP.NomCom AS CommunePersonne.... Ici, tu n'auras plus de colonne NomCom dans ton jeu de résultat, mais à la place tu auras une colonne CommuneObs et une colonne CommunePersonne. Un petit peu plus parlant, surtout dans quelques mois quand si tu dois revenir sur ton code
    --- Sevyc64 ---

    Parce que le partage est notre force, la connaissance sera notre victoire

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2015
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2015
    Messages : 7
    Points : 8
    Points
    8
    Par défaut
    Bonsoir.

    Tout d'abord désolé pour le retard avec lequel je vous réponds, j'ai été assez occupé ces derniers jours. Quoi qu'il en soit merci infiniment pour vos explications qui m'ont complètement débloqué dans mon problème !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT * FROM Tobs O
    INNER JOIN TPers P ON O.IDPers=P.IDpers
    INNER JOIN TCom C ON O.INSEEobs=C.INSEE
    INNER JOIN Tcom CP ON P.INSEE=CP.INSEE
    Tu constatera, avec ce code qui doit fonctionner, que sont retournés l'ensemble des champs de chaque table, que donc les champs de la table commune sont retournés 2 fois mais avec des données différentes puisque ce n'est pas le même lien.
    Tu constatera d'ailleurs que le second jeu de champs de la table commune ont été automatiquement renommés pour ne pas les confondre avec le premier jeu.
    Tout cela est dû au SELECT * qui retourne tout.
    Je comprends au final, l' "astuce" si je puis me permettre consiste donc à appeler deux fois la table TCom et à lui donner deux alias différents afin de pouvoir clairement faire la jointure. Je ne pensais pas qu'on pouvais ainsi utiliser une table plus d'une fois ; l'assistant de création de requête Access m'a un peu bloqué dans cette idée puisqu'en ayant appelé une fois la table Tcom je n'imaginais pas avoir besoin d'un autre exemplaire.

    Une autre question concernant la casse : dans votre code je constate que vous avez écrit Tcom ou TCom indifféremment ; j'imagine que si Access possède une certaine souplesse sur la casse ce n'est pas forcément le cas de tous les logiciels et qu'il vaut mieux être rigoureux sur la casse dans tous les cas ?

    Par ailleurs je crois voir qu'Access a la mauvaise idée de modifier le code SQL à sa sauce quand on repasse en mode assistant ce qui me semble peu pratique ! Je vois l'intérêt de tout coder directement en SQL, ce qui me paraît effectivement plus sûr !

    En ce qui concerne le nommage des champs on nous a effectivement incité à toujours préciser la table d'origine afin d'éviter toutes les ambiguïtés.

    J'imagine donc qu'en suivant la logique du dernier code je peux rajouter des jointures à la queue-leu-leu si j'ai besoin d'informations d'autres tables ? Tant que le code est bon cela ne devrait pas poser de question ?

    Une dernière question sur les jointures, justement. Si on prend le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SELECT * FROM Tobs O
    INNER JOIN TPers P ON O.IDPers=P.IDpers
    je constate qu'il suffit de préciser une seule des tables reliée (ici TPers) tant qu'on précise les champs des deux tables correspondants. Est-ce que cela veut dire que la jointure fonctionne en quelque sorte dans "un seul sens" (par exemple ici : une personne pour chaque observation mais pas forcément une seule observation par personne) ? Dans ma logique j'aurais spontanément précisé les deux tables à joindre puisque... hé bien une jointure relie deux tables ! Est-ce une petite spécificité du langage SQL ou y'a-t-il une explication logique à cela ?

    En gros est-ce que la logique consiste à partir d'une table initiale et de dérouler toutes les jointures les unes derrières les autres en "guirlande" ?


    Dans tous les cas la question d'origine est résolue, merci à vous d'avoir pris le temps de m'aider tout en restant accessible et pédagogique ! J'ai compris la logique derrière mon problème, même si j'ai encore quelque difficultés en langage SQL j'imagine que ça viendra avec la pratique !

    Bonne soirée à vous.

  6. #6
    Modérateur
    Avatar de sevyc64
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2007
    Messages
    10 193
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 193
    Points : 28 077
    Points
    28 077
    Par défaut
    Citation Envoyé par BModjo Voir le message
    Je comprends au final, l' "astuce" si je puis me permettre consiste donc à appeler deux fois la table TCom et à lui donner deux alias différents afin de pouvoir clairement faire la jointure. Je ne pensais pas qu'on pouvais ainsi utiliser une table plus d'une fois ; l'assistant de création de requête Access m'a un peu bloqué dans cette idée puisqu'en ayant appelé une fois la table Tcom je n'imaginais pas avoir besoin d'un autre exemplaire.
    C'est effectivement comme si tu intégrais 2 tables différentes, elles sont vues comme telle dans les jointures.
    Et il est vrai qu'Access n'est pas forcément le meilleur allié pour travailler directement sur du sql.

    Citation Envoyé par BModjo Voir le message
    Une autre question concernant la casse : dans votre code je constate que vous avez écrit Tcom ou TCom indifféremment ; j'imagine que si Access possède une certaine souplesse sur la casse ce n'est pas forcément le cas de tous les logiciels et qu'il vaut mieux être rigoureux sur la casse dans tous les cas ?
    A ma connaissance, la plupart des SGBD ne sont pas sensible à la casse concernant les mots clés comme SELECT, les noms des tables et les noms des champs. Par contre il en va pas de même avec le contenu des champs. Suivant le paramétrage de ta base, si TPers.Prenom contient 'Pierre' et que toi tu cherche 'pierre' ou 'PIERRE', tu ne le trouveras pas.
    Il en va de même avec les caractères accentués et les caractères spécifiques à certaines langues.

    Citation Envoyé par BModjo Voir le message
    Par ailleurs je crois voir qu'Access a la mauvaise idée de modifier le code SQL à sa sauce quand on repasse en mode assistant ce qui me semble peu pratique !
    Access a un comportement assez particulier et assez déroutant y compris avec le code SQL. Tu verra que parfois il faut user et abuser des ( ) pour arriver à lui faire comprendre les choses.

    Citation Envoyé par BModjo Voir le message
    J'imagine donc qu'en suivant la logique du dernier code je peux rajouter des jointures à la queue-leu-leu si j'ai besoin d'informations d'autres tables ? Tant que le code est bon cela ne devrait pas poser de question ?
    Tu peux.

    Citation Envoyé par BModjo Voir le message
    je constate qu'il suffit de préciser une seule des tables reliée (ici TPers) tant qu'on précise les champs des deux tables correspondants. [...] Dans ma logique j'aurais spontanément précisé les deux tables à joindre puisque... hé bien une jointure relie deux tables
    Non, non, les 2 tables sont bien précisées. JOIN TPers Indique que tu lie la table TPers à une des tables déjà précisée auparavant. La clause ON qui suit indique comment tu fais le lien mais aussi implicitement avec quelle table déjà précisée, tu fais le lien, en l'occurence O donc TObs.
    Tu as donc bien le lien Tobs JOIN TPers. Et dans les jointures suivantes, tu ne répète pas TObs puisque tu l'as déjà mis une fois, mais ça revient à le faire.

    Citation Envoyé par BModjo Voir le message
    Est-ce que cela veut dire que la jointure fonctionne en quelque sorte dans "un seul sens"
    De manière générale, sans entrer dans le détail, une jointure s’interprète toujours de gauche à droite même si certaines jointures, par leurs spécificités, s'appliquent ensuite de droite à gauche.

    Le JOIN tu dit effectivement au départ "une personne pour chaque observation". Le INNER, lui, va te dire "les observations obligatoirement faites par une personne". Ça veut dire que les observations dont il n'ai pas trouvé de lien avec la table TPers (en gros O.IDPers = null) ne seront pas retournées.
    Par contre, "mais pas forcément une seule observation par personne", ceci n'est effectivement pas spécifier ici.

    Citation Envoyé par BModjo Voir le message
    En gros est-ce que la logique consiste à partir d'une table initiale et de dérouler toutes les jointures les unes derrières les autres en "guirlande" ?
    C'est en gros le principe. Les jointures partent en toile d'araignée depuis une table principale.
    Et même, avec exactement les mêmes tables jointes, sur les mêmes critères, suivant la table prise en table principale, le résultat ne sera pas le même.

    Ces 2 requêtes, pourtant très peu différentes, ne te renverront pas du tout le même résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SELECT * FROM Tobs O
    INNER JOIN TPers P ON O.IDPers=P.IDpers
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SELECT * FROM TPers P
    INNER JOIN Tobs O ON O.IDPers=P.IDpers
    --- Sevyc64 ---

    Parce que le partage est notre force, la connaissance sera notre victoire

  7. #7
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 080
    Points : 30 801
    Points
    30 801
    Par défaut
    Citation Envoyé par sevyc64 Voir le message
    Ces 2 requêtes, pourtant très peu différentes, ne te renverront pas du tout le même résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SELECT * FROM Tobs O
    INNER JOIN TPers P ON O.IDPers=P.IDpers
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SELECT * FROM TPers P
    INNER JOIN Tobs O ON O.IDPers=P.IDpers
    Tu es vraiment sûr de ce que tu avances ?
    Avec un LEFT JOIN, ce serait vrai, mais pas un INNER JOIN... ou alors ton SGBD fonctionne d'une manière particulière.
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  8. #8
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    L'ordre des colonnes dans le select sera différent, mais ce seront in fine les mêmes données.

  9. #9
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2015
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2015
    Messages : 7
    Points : 8
    Points
    8
    Par défaut
    C'est parfait, j'ai eu la réponse à toutes mes questions et ma base de données fonctionne comme je le désirais.

    Merci encore à vous pour vos réponses ! Et merci de partager votre expérience en la matière pour aider les plus débutants à progresser !

    Je rencontre un autre problème sur un formulaire cette fois-ci ; je me suis permis de créer un nouveau sujet puisque le problème est quelque peu différent et de passer celui-ci en "Résolu" !

  10. #10
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 136
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 136
    Points : 38 909
    Points
    38 909
    Billets dans le blog
    9
    Par défaut
    Peut être Est-ce du au fait que c'est un exercice, mais voici quelques remarques en marge de vos questions :

    - il manque une entité correspondante à une session d'observation, et qui devrait comporter les attributs
    identifiant session, observateur, lieu, date, marée, météo
    - il manque une entité correspondante à une observation et qui devrait comporter les attributs
    identifiant session, identifant obs, espèce observée, effectif
    - idéalement, on peux noter les conditions météorologiques liées aux lieux et à la date (la météo a une grosse influence sur les mouvements des populations)
    - l'espèce ne devrait pas être liée à la famille, mais au genre, c'est le genre qui est lié à la famille

  11. #11
    Modérateur
    Avatar de sevyc64
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2007
    Messages
    10 193
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 193
    Points : 28 077
    Points
    28 077
    Par défaut
    Oups, j'avais un peu zappé les réponses ici.

    Concernant la remarque d'escartefigue, elle n'est effectivement pas insensée. A la nuance près (que je renuancerais encore par la suite) , que l'on ne connais pas le besoin final. Elle n'est pas insensée si on a effectivement besoin des ces infos là.

    Par ex, si une session=une observation et une observation=une session, on a pas forcément besoin de la table de correspondance, la table observation doit suffire. L'information sur la météo est surement pertinente, mais si elle ne doit pas du tout être utilisée. Idem pour l'information sur le genre (je n'y connais rien, je me permet pas de remettre en cause l'argument d'escartefigue), si l'information n'est pas utile, pas besoin de compliquer. Si une espèce est liée à un genre, si un genre est lié à une famille, une espèce est donc liée même indirectement à une famille. Si le genre n'est pas utile ....

    Le problème de la modélisation d'une BDD est justement de définir le besoin. Parce qu'il ne faut uniquement définir le besoin immédiat mais aussi prendre en compte, dans la limite de l'imaginable et du prédictible, ce que pourrait (et pourra) être ce besoin dans le futur.
    En effet, ça suffit pas de dire, "ces données ne sont pas utiles aujourd'hui il n'est pas nécessaire de les intégrer", comme je viens de le faire. Si on sait déjà que potentiellement elles pourront devenir utiles dans l'avenir selon l'évolution imaginable du besoin, ça sera dommage dès maintenant de """"mal"""" modéliser la BDD et de ne pas, au minimum, prévoir la possibilité d'une intégration.

    Tout ça pour dire que parfois c'est un jeu d'ajustement et compromis et que ce n'est pas toujours simple.



    Concernant, mes propos sur la différences de résultats avec les 2 requêtes. Avec des jointures internes, et sur ces requêtes simple là, je me suis effectivement un peu emballé. Ces requêtes doivent renvoyer le même résultat.
    Il peut arriver voir des différences apparaitre dans le cas de la présence de clause Where et suivant ce qu'il y a dans cette clause. Pas toujours évidente à comprendre d'ailleurs. Dsl, j'ai pas d’exemple sous la main sinon, j'aurais partagé. J'ai eu un cas une fois qui m'a bien occupé (avec un where bien complexe) avant de comprendre que dans la logique la requete démarrait sur la mauvaise table. Juste d'inverser la table principale, le plan d’exécution n'était pas le même et le résultat différait, pas énormément, mais justement sur les cas qui nous intéressaient.

    Là, par contre, ou on voit ce problème là, systématiquement, c'est sur les requêtes externe (LEFT JOIN, et RIGHT JOIN) ou là, la définition de la table principale est très important
    --- Sevyc64 ---

    Parce que le partage est notre force, la connaissance sera notre victoire

  12. #12
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 136
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 136
    Points : 38 909
    Points
    38 909
    Billets dans le blog
    9
    Par défaut
    Citation Envoyé par sevyc64 Voir le message
    Par ex, si une session=une observation et une observation=une session, on a pas forcément besoin de la table de correspondance, la table observation doit suffire
    Il se trouve que je connais bien le sujet pour avoir fait des campagnes de relevés d'oiseaux pendant des années
    Il faut bien 2 entités distinctes, si l'on ne veut pas avoir à répéter pour chaque espèce observée, le lieu, la météo, la marée etc.
    Au cours d'une même session, on peut observer plusieurs dizaines d'espèces, il n'est donc pas du tout pertinent de faire une entorse aux formes normales sur ce point.

    Citation Envoyé par sevyc64 Voir le message
    Si une espèce est liée à un genre, si un genre est lié à une famille, une espèce est donc liée même indirectement à une famille. Si le genre n'est pas utile ....
    Par contre ici, on peut effectivement simplifier le modèle, car le genre est porteur de peu d'informations et l'application ne souhaite peut être pas gérer ces infos.
    Mais je préfère mentionner cette petite faute, car il faut en avoir conscience pour ne pas bloquer d'éventuelles évolutions futures, après le choix est libre bien sur

    Concernant la météo, j'avais mis "idéalement" une entité séparée
    Mais, dans les faits il est très peu probable qu'on soit en capacité de relever la météo pour l'ensemble des sites d'observation à moins de se synchroniser avec météo-france.
    C'est dommage car la météo des jours qui ont précédé l'observation, est encore plus importante (elle explique très souvent des départs ou des arrivées de populations importantes)
    C'est pourquoi, j'ai rapatrié l'info dans la table des sessions

  13. #13
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2015
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2015
    Messages : 7
    Points : 8
    Points
    8
    Par défaut
    Bonjour, et merci pour vos réactions.

    Je ne l'avais pas précisé initialement pour ne pas alourdir inutilement le sujet, mais il s'agit bien d'une base de données d'exercice qui ne servira pas en pratique. Nous avons reçu un jeu de données non optimisées sous Excel et l'objectif était d'en déduire une base de données optimale à partir de celles-ci. Effectivement il aurait été pertinent de créer des tables supplémentaires pour la classification (genre et groupes supérieurs) ou pour les sessions d'observation ou la météo, néanmoins nous ne possédions pas ces données et nous avons reçu pour consigne de ne considérer que les données fournies afin de se concentrer sur l'aspect technique de la réalisation de la base. Les données reçues étant de toute façon très probablement inventées pour le bénéfice de l'exercice.

    Je ne doute pas néanmoins que pour une utilisation réelle, une telle base serait largement incomplète et mériterait qu'on s'y attarde plus selon les besoins attendus. Pour cet exercice la base que j'ai conçue suffit amplement.

  14. #14
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 768
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 768
    Points : 52 719
    Points
    52 719
    Billets dans le blog
    5
    Par défaut
    Citation Envoyé par BModjo Voir le message
    ...Effectivement il aurait été pertinent de créer des tables supplémentaires pour la classification (genre et groupes supérieurs) ou pour les sessions d'observation ou la météo....
    Pas pertinent... Essentiel et fondamental.
    Une règle absolue de modélisation est que :
    "le changement d'une information ne doit pas affecter plus d'une ligne"
    En ne mettant pas ceci dans des tables de référence vous allez systématiquement rencontrer le problème.
    Exemple : nos politiciens qui n'ont que cela a foutre (surtout en ce moment) ont décidé de supprimer les "demoiselle" et de les faire devenir des "madame" sous prétexte d’égalité des sexes...
    Combien de lignes impactées pour ce seul changement d'information ?

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

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

Discussions similaires

  1. Créer par code des relations entre tables d'une même base ?
    Par AndréPe dans le forum Modélisation
    Réponses: 2
    Dernier message: 21/11/2007, 18h27

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo