Partage
  • Partager sur Facebook
  • Partager sur Twitter

Conception base de données

Sujet résolu
    15 novembre 2017 à 14:42:24

    Bonjour,

    J'ai des soucis dans la conception de ma base de données.

    Celle-ci se compose d'une table CONNECTION contenant des informations sur des serveurs.

    Chaque serveur de ma table CONNECTION peut être associé à 0,1 ou plusieurs instances.

    J'avais pensé utiliser le type enum et ajouter une colonne dans ma table CONNECTION avec ma liste d'instances. Cependant, il semblerait que l'utilisation de ce type ne soit pas conseillé. De plus ma liste d'instances est amenée à évoluer et je n'ai pas envie de modifier mon schéma de base à chaque nouvelle instance.

    J'ai donc pensé à faire une table ASSOCIATION de ce genre :

    ID       INSTANCE_NAME         ID_SERVER
    1        INSTANCE1                  10
    2        INSTANCE2                  10
    3        INSTANCE2                  11   

    De cette façon je peux déterminer les instances associés à chaque serveur.            

    Sauf que maintenant, il faut que j'arrive à faire le lien entre ma table ASSOCIATION et mes instances et la je bloque. Chaque instance (INSTANCE1, INSTANCE2 ... INSTANCEX) est une table spécifique. Je vais donc avoir X tables pour représenter mes X instances. Mais comment faire, par exemple, pour récupérer les informations de mes INSTANCE1 et 2 pour le serveur avec l'id 10 ? En plusieurs requêtes je vois comment m'en sortir mais j'ai l'impression que c'est plus du bricolage qu'autre chose ...

    Je n'ai pas beaucoup d'xp en conception de bdd donc peut être que je ne m'y prends pas du tout comme il faut ?

    Merci

    • Partager sur Facebook
    • Partager sur Twitter
      15 novembre 2017 à 14:58:31

      Bonjour,

      hachebourin a écrit:

      Chaque instance (INSTANCE1, INSTANCE2 ... INSTANCEX) est une table spécifique

      Euhhhh ... Pourquoi ?

      Là, sans plus de précision, c'est une erreur de conception de faire X tables ...

      Tu as des serveurs et des instances. 2 entités donc 2 tables.

      Une instance correspond à un serveur, et un serveur est associé à plusieurs instances. C'est une relation 1,n, donc une clé étrangère dans la table instance ...

      Si cela est correct, ton modèle devrait simplement être :

      • serveur ( id_serveur [pk], etc. )
      • instance ( id_instance [pk], id_serveur [fk], etc. )

      C'est tout ... pas besoin de multiplier les tables d'instance, ni de faire une table de relation ...

      -
      Edité par Benzouye 15 novembre 2017 à 14:58:52

      • Partager sur Facebook
      • Partager sur Twitter
      Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
        15 novembre 2017 à 15:17:47

        En fait, il faut voir une instance un peu comme un serveur mais en plus spécifique.

        Exemple d'info serveur : IP_SVR, HOSTNAME, LOGIN ...
        Exemple d'info instance apache : IP_APA, PORT_APA, SSL_ON ...
        Exemple d'info instance tomcat : IP_TOM, PORT_TOM, SSL_ON ...

        Ainsi, certains serveurs pourront avoir des instances apache et tomcat alors que d'autres auront uniquement une instance apache.

        Du coup, je dois avoir une table pour définir chacune de mes instances (apache, tomcat ...)

        J'ai pris l'exemple d'instance web mais il pourrait y avoir des instances mysql ou autre chose ... les colonnes de mes instances ne sont pas forcément les mêmes.

        Je pourrais faire comme tu as dit mais je risque d'avoir énormément de colonne vide en fonction des instances. Et puis je ne pourrais pas savoir facilement quelles sont les données spécifiques à chaque instance si je mets tout dans une même table.

        • Partager sur Facebook
        • Partager sur Twitter
          15 novembre 2017 à 15:55:14

          Cela ne change pas vraiment ma réponse précédente, mais ajoute juste la notion d'héritage (un peu de lecture).

          Une instance est une entité mère et une instance tomcat est une entité fille qui hérite de l'entité mère ...

          Ainsi, tu maintiens la première partie du modèle :

          • serveur ( id_serveur [pk], etc. )
          • instance ( id_instance [pk], id_serveur [fk], etc. )

          Dans la table instance tu ne laisses que les attributs commun à toutes les instances ... nom, date de création, IP, etc.

          Ensuite tu vas créer une table par type d'instance :

          • instance_tomcat ( id_instance [pk][fk], attribut_tomcat1, attribut_tomcat2, etc. )
          • instance_apache ( id_instance [pk][fk], attribut_apache1, attribut_apache2, etc. )
          • ainsi de suite ...

          Ce modèle a l'avantage de disposer pour chaque type d'instance d'une table dédiée avec ses propres attributs.

          Inconvénient de ce modèle, si tu dois ajouter/modifier/supprimer des types d'instance, cela t'oblige à modifier le modèle, ce que tout bon développeur préfère éviter autant que possible ... Donc si la liste des types d'instance est susceptible de fréquemment évoluer il faudrait éviter ce modèle :p

          Autre possibilité, plus fexible mais aussi moins rigoureuse, les méta-données ...

          Tu vas avoir des serveurs, des types d'instance (tomcat, apache, mysql, etc.), des attributs (PORT, SSL, etc.), des instances. 4 entités donc 4 tables.

          En terme de relation :

          • une instance est d'un seul type, et un type peut regrouper plusieurs instances. Relation 1,n, donc clé étrangère dans la table instance
          • un attribut peut être associé à plusieurs type d'instance, et un type d'instance peut posséder plusieurs attributs. Relation n,n, donc une table de relation.
          • un attribut peut être associé à plusieurs instances, et une instance peut posséder plusieurs attributs, chacun avec sa valeur. Relation n,n, donc une table de relation.

          Le modèle serait alors :

          • type_instance ( id_type [pk], libelle ) pour stocker les types possibles (apache, tomcat, mysql, etc.)
          • attribut ( id_attribut [pk], libelle ) pour stocker les attributs possibles (hostname, login, port, ssl, etc.)
          • attribut_type ( id_attribut [pk][fk], id_type [pk][fk] ) pour lier un type à ses attributs
          • serveur ( id_serveur [pk], etc. ) pour stocker les serveurs
          • instance ( id_instance [pk], id_type [fk], id_serveur [fk], ip, etc. )
          • instance_attribut ( id_instance [pk][fk], id_attribut [pk][fk], valeur ) pour stocker la valeur d'une attribut pour une instance

          Alors oui, le modèle est plus gros, mais plus souple et surtout évolutif ... Pour ajouter un type il suffit de le créer dans la table, de créer ses attributs, et de relier le type à ses attributs.

          Lorsque tu crées une instance, tu précises son type, tu récupères les attributs liés pour proposer à l'utilisateur de saisir une valeur pour chacun.

          Problème majeur : la table attribut contient un seul type de données, en général on choisit un VARCHAR assez grand, ce qui peut être gênant et obliger de caster les données pour pouvoir faire des calculs ou des agrégats.

          • Partager sur Facebook
          • Partager sur Twitter
          Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
            16 novembre 2017 à 11:14:23

            Merci pour cette réponse bien detaillé :)


            Juste quelques questions concernant le premier modèle :


                - Que veux-tu dire lorsque tu écris [pk][fk] :  id_instance[pk][fk] ?
                - Concernant l'évolution du modèle, je ne vois pas ça très gênant d'ajouter/modifier/supprimer une instance. Je suis d'accord pour dire que ce n'est pas une bonne pratique mais je ne vois pas l'impact que ça peut avoir puisque ce sont des tables indépendantes.
                - J'ai quand même l'impression qu'il manque quelque chose dans ce modèle. Comment dois-je faire pour savoir quel type d'instance est associé à un serveur ? Je suis obligé de checker chacune de mes tables instances_x ? Même si je rajoute une table association pour dire que tel serveur est associé à tel instance, je vais devoir mettre une colonne avec le nom de ma table instance pour ensuite sélectionner la bonne table instance ? J'ai l'impression que ce n'est pas la bonne façon faire.

            Pour le deuxième modèle je ne vois pas pourquoi tu dis que c'est moins rigoureux ? Est-ce à cause du problème majeur ? En dehors de ça, je le trouve vraiment bien grâce à sa flexibilité.

            • Partager sur Facebook
            • Partager sur Twitter
              16 novembre 2017 à 11:45:39

              hachebourin a écrit:

              Que veux-tu dire lorsque tu écris [pk][fk]

              • PK = Primary Key, clé primaire
              • FK = Foreign Key, clé étrangère

              hachebourin a écrit:

              Concernant l'évolution du modèle, je ne vois pas ça très gênant d'ajouter/modifier/supprimer une instance

              En fait, il ne faut pas regarder simplement la base de données, mais l'envisager dans son environnement. Tu vas sûrement avoir une application qui communique avec ta BDD pour assurer l'interface utilisateur. Le code de cette application va devoir disposer de requêtes permettant d'insérer, de lire, de modifier, et de supprimer les enregistrements en base.

              Dans ce contexte, la modification de modèle de données (ajout d'une table) va t'obliger de modifier également le code applicatif pour intégrer cette modification ... Ce n'est pas maintenable ... à moins de travailler avec des variables sur les noms de table ce qui n'est pas top ...

              hachebourin a écrit:

              Comment dois-je faire pour savoir quel type d'instance est associé à un serveur ?

              Je ne sais pas de quel modèle tu parles ... Dans les modèles que je te propose chaque instance est liée à un serveur (et un seul) par sa clé étrangère ...

              Dans le cas de l'héritage ( http://sqlpro.developpez.com/cours/modelisation/heritage/ ), c'est l'existence de l'id de la table mère dans une des tables fille qui te permet de déterminer de quel type est l'instance.

              Pour éviter qu'une instance puisse avoir plusieurs type il faut mettre en place un système de TRIGGER t'empêchant d'insérer dans une table fille un id_instance existant déjà dans une autre table fille, ce qui me permet de recouper avec ta question précédente : si tu rajoutes une table fille, tu devras modifier également tous les TRIGGER assurant ce contrôle d'intégrité ... pas cool ...

              • Partager sur Facebook
              • Partager sur Twitter
              Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
                16 novembre 2017 à 13:31:51

                Ah mais oui, une colonne peut être clé primaire et étrangère en même temps. Autant pour moi ...

                Pour l'évolution tu as raison. Je n'avais en tête que des applications bien précise qui ne sont pas impactées par l'ajout d'instances ...

                Et enfin, pour le dernier point, ma question concernait uniquement le premier modèle. Je vois bien que chaque instances est liée à un serveur cependant ce que je n'arrive pas à comprendre c'est comment récupérer les infos d'une instance précise ?

                Par exemple si j'ai un serveur associé à une instance apache. Je vais facilement avoir l'information comme quoi ce serveur est lié à cette instance apache. Mais ensuite, comment faire pour récupérer les infos de l'instance en question ? Comment savoir que je vais devoir chercher précisément dans la table instance_apache et non pas dans instance_tomcat ?

                • Partager sur Facebook
                • Partager sur Twitter
                  16 novembre 2017 à 13:48:44

                  hachebourin a écrit:

                  Comment savoir que je vais devoir chercher précisément dans la table instance_apache et non pas dans instance_tomcat ?

                  C'est la difficulté de l'héritage en SQL ... Au passage, tout cela est expliqué dans le lien que je t'ai donné :-°

                  Pour déterminer de quel type est une instance, il faut rechercher dans toutes les tables filles où se trouve l'instance voulue :

                  SELECT I.id_instance, 'apache' AS type_instance
                  FROM
                      instance I
                          INNER JOIN instance_apache AI
                              ON I.id_instance = AI.id_instance
                  
                  UNION
                  
                  SELECT I.id_instance, 'tomcat' AS type_instance
                  FROM
                      instance I
                          INNER JOIN instance_tomcat TI
                              ON I.id_instance = TI.id_instance
                  
                  UNION
                  
                  ...

                  Cela peut faire l'objet d'une vue pour te simplifier la tâche ;)

                  Si ton jeu de TRIGGER est bien fait, une telle requête ne devrait toujours te retourner qu'une seule ligne. Une fois que tu connais le type, tu peux demander à ton programme d'exécuter la requête spécifique au type dans un switch/case par exemple.

                  Sinon, tu peux ajouter d'une colonne "type instance" dans la table mère, qui te permet de savoir de quel type est l'instance avant de décider quelle requête exécuter ... Cette colonne devra être mise à jour par un TRIGGER AFTER INSERT sur chaque table fille ... et en soit, brise le principe d'atomicité puisque l'information est redondante et que tu risques une perte d'intégrité si la colonne n'est pas renseignée ou pas mise à jour ...

                  Je persiste à dire que dans ton contexte le modèle "méta-données" est plus pertinent et plus flexible, et t'évite bien des tracas de programmation ...

                  -
                  Edité par Benzouye 16 novembre 2017 à 13:51:05

                  • Partager sur Facebook
                  • Partager sur Twitter
                  Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
                    17 novembre 2017 à 12:03:51

                    Tout à fait, j'avais l'intention d'utiliser le modèle "méta-données" mais je voulais d'abord comprendre comment fonctionnait le premier modèle. Et maintenant tout est clair :)

                    Je trouve juste un peu dommage de devoir faire une recherche dans toutes les tables filles. J'espérais quelque chose de plus "intelligent".

                    Encore merci pour toutes ces réponses :)

                    • Partager sur Facebook
                    • Partager sur Twitter

                    Conception base de données

                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                    • Editeur
                    • Markdown