Partage
  • Partager sur Facebook
  • Partager sur Twitter

L'héritage et les requêtes

Quelles sont les bonnes pratiques

Sujet résolu
    21 janvier 2022 à 20:01:56

    Bonjour chers développeurs !

    Je suis sur un projet qui m'a amené a m'intéresser à l'héritage en base de donnée. C'est une notion que je n'ai jamais appris, je fait donc face à des problématiques assez embêtantes. C'est pourquoi je viens chercher de l'aide auprès de vous dans l'espoir d'y voir plus clair. 

    Voici la partie de ma BD qui nous intéresse : 

    C'est donc une BD pour le site web d'une boucherie qui à également un petit service de fromagerie et d'épicerie. 

    Il y à donc une table produit dans laquelle on va retrouver aussi bien des fromages que des viandes, des oeufs, etc ... Chacun d'eux ayant des propriétés différentes, j'ai été obligé de faire appel à l'héritage. J'ai donc, grâce aux renseignements trouvés sur internet, réussi à créer ma base de donner. 

    La ou j'ai un problème, c'est que j'ai du mal à comprendre comme je vais faire mes requêtes.

    1. Comment vais-je faire pour insérer un nouveau produit ? 

    Ma première idée serait de faire un INSERT dans ma table produit puis de faire un deuxième insert dans ma table autre, viande ou fromage. Mais j'ai le sentiment que ce n'est pas une bonne pratique.

    2. Quand je fait un SELECT sur un de mes produits, comment savoir de quel type il est ? (fromage, viande ou autre)

    Dois-je faire un select avec l'id du produit sur chacune des table jusqu'à le trouver dans une d'entre elles ? La encore, je n'ai pas l'impression que ce soit la bonne méthode.

    3. Si je veux afficher TOUT mes produits (dans un catalogue par exemple)

    Dois-je faire un SELECT sur chacune de mes tables ? 

    Vous l'aurez compris, je n'ai vraiment aucune notion dans le domaine de l'héritage. Mais je suis bien décider à apprendre. Si une bonne âme passe par ici, je serais ravi de recevoir des conseils. 

    Merci. 

    -
    Edité par AxelBertrand5 21 janvier 2022 à 20:13:17

    • Partager sur Facebook
    • Partager sur Twitter
      22 janvier 2022 à 14:42:30

      Bonjour je vais essayer de vous faire un exemple simplifier pour que vous compreniez le tout

      mais déjà il vous faudra des notions de requêtes mutlitable ce qui répond aux questions 2 et 3

      On a comme probleme : représenter les equipe de foot de 3 pays sachant qu'un pays à deux équipes de foot

      quand tu découpes le problème : une equipe de foot à 11 joueurs - donc représenter le joueur - representer l'equipe (on va dire un club) - une equipe de foot appartient à un pays - et donc représenter le pays

      country(country_id,name,...)

      player(player_id,name,age,...)

      club(club_id,name,...)

      ensuite vous aurez les associations suivantes

      (1,n | 1,1 | 0,1 | 0,n) -> les cardinalités en fonction de ça tu peux créer un automatisme pour générer les tables finales (évidemment si elles sont bien faîtes)

      exemple:une cardinalité du style player 0,n -> 0,n club c'est que tu vas créer une troisieme table qui aura club_id,player_id + autre chose comme clé primaire

      club 1,n (have) 1,1 player -> un club à 1 à plusieurs joueurs - un joueur appartient à 1 club

      country 1,n (have) 1,1 club -> un pays à 1 à plusieurs club - un club appartient à un pays

      (je te conseille d'utiliser un logiciel comme looping qui représentera ça et tu veras les tables que ca donne à la fin ca aidera à la compréhensioon)

      ici tu auras les tables

      country = (country_id , name );
      club = (club_id , name , #country_id);
      player = (player_id , name , age , #club_id);

      maintenant quand tu vas vouloir selectionner par exemple le nom de tous les joueurs d'un club que tu auras choisis

      select player.name from club,player where club.name = "nom_du_clum" and player.club_id = club.club_id;

      le nom de tous les joueurs d'un pays

      select player.name from country,club,player where country.name = "nom_du_pays" and country.country_id = club.country_id and player.club_id = club.club_id

      tu fais des liaisons entre les tables via les clé étrangères

      pour certaines requetes tu auras des inner / outer join tatata mais la base est là .



      -
      Edité par zvheer 22 janvier 2022 à 14:45:15

      • Partager sur Facebook
      • Partager sur Twitter

      yasakani no magatama

        22 janvier 2022 à 20:10:17

        zvheer tu te trompes je pense.

        Quand le lien entre 2 entités est "entité 1 est entité 2" c'est de l'héritage.

        Quand le lien est "entité 1 a entité 2", entité 1 est une table, entité 2 son attribut. Si la valeur d'entité 2 se duplique, on crée une table supplémentaire.

        Dans ton exemple, Un pays a un club qui a des joueurs.

        Je partirais davantage sur un animal est un mammifère OU un oiseau OU un reptile (etc.)

        • Partager sur Facebook
        • Partager sur Twitter
          23 janvier 2022 à 9:57:48

          Re-bonjour, Merci beaucoup Zvheer pour ta réponse. Mais effectivement, ça ne répond pas vraiment à ma problématique d'héritage. :p
          • Partager sur Facebook
          • Partager sur Twitter
            24 janvier 2022 à 14:56:45

            Bonjour,

            AxelBertrand5 a écrit:

            1. Comment vais-je faire pour insérer un nouveau produit ? 

            Ma première idée serait de faire un INSERT dans ma table produit puis de faire un deuxième insert dans ma table autre, viande ou fromage. Mais j'ai le sentiment que ce n'est pas une bonne pratique.

            C'est pourtant bien ainsi qu'il faudra fonctionner. Insérer dans la table mère, récupérer l'id créé ( avec LAST_INSERT_ID() )et insérer dans la table fille avec cet id.

            AxelBertrand5 a écrit:

            2. Quand je fait un SELECT sur un de mes produits, comment savoir de quel type il est ? (fromage, viande ou autre)

            Pour ma part, j'aurai créé une colonne "type" dans la table produit. Sinon, il faut faire des jointures externes sur chaque table fille pour déterminer quel type correspond.

            AxelBertrand5 a écrit:

            3. Si je veux afficher TOUT mes produits (dans un catalogue par exemple)

            On retombe sur ma remarque précédente.

            • Partager sur Facebook
            • Partager sur Twitter
            Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
              24 janvier 2022 à 16:47:26

              Pour la MCD, je ferais une ternaire (provenir de) entre des tables PRODUIT, SOUS_CATÉGORIE et ORIGINE. J'y mettrais 3 clés étrangères qui font référence aux tables liées. Ensuite, je lierais la table SOUS_CATÉGORIE à une table CATÉGORIE avec une relation (appartenir).

              Pourquoi la ternaire ? Exemple, tu vends un plat préparé contenant des coquillettes (sous catégorie de pâtes et féculents), les pâtes et féculents font partie de la catégorie épicerie. Ces coquillettes provienne d'un endroit A. Ensuite, ce plat préparé a de la viande de porc que tu ne veux pas mettre dans la catégorie des viandes, la sous catégorie est porc transformé qui appartient à la catégorie viande transformée. Cette viande proviendrait d'un endroit B différent de A.

              En admettant que ce plat préparé soit identifié 123, en liant les sous-catégories correspondantes, puis en les liant à la catégorie épicerie générale, tu as la catégorie générale du plat préparé.

              Pour l'insertion, tu peux faire remplir un formulaire par les fournisseurs, tu mets la liste des produit en liste d'attente et tu fais les vérifs et tu insères les nouveaux produits.

              • Partager sur Facebook
              • Partager sur Twitter
                24 janvier 2022 à 22:09:02

                Merci beaucoup pour vos réponse, j'y vois un peu plus clair. Si quelqu'un a encore d'autre conseils pour moi concernant ce concept d'héritage je suis vraiment preneur. Merci encore :lol:
                • Partager sur Facebook
                • Partager sur Twitter
                  24 janvier 2022 à 23:26:05

                  N'attends pas les conseils et fais cette BDD. De toute façon, la BDD parfaite n'existe pas, tu vas te planter. Donc, tu la fais, tu la manipules et tu notes toute manipulation laborieuse. Tu cherches comment faire des optimisations et tu sors une version 2 et ainsi de suite.

                  J'ai passé quelques heures à élaborer un MCD, je l'avais terminé et au moment de faire les cardinalités je me suis aperçu que je devais optimiser mes jointures.

                  La différence entre toi et moi, c'est que tu as un boulot à faire, alors que je peux m'amuser à faire 50 MCD, à part du temps, je ne vais rien perdre.

                  Selon moi, il faut une BDD qui soit optimale, pour les utilisateurs plus que pour l'ordinateur, sur les opérations. C'est pas grave si un SELECT met 5 secondes, alors que le même SELECT optimisé n'en met qu'1. Il y a 4 opérations (Création, suppression, mise à jour, lecture). Du point de vue des utilisateurs, les opérations de création sont rapides. Les opérations de suppression sont relativement rares mais doivent être bien configurées, les opérations de mise à jour (j'y inclus l'insertion de nouvelles données) et de lecture sont lourdes mais on peut faire des scripts d'automatisation avec un langage de prog ou dans le logiciel du SGBDR si c'est possible.

                  J'ai fait une BDD simple, il te suffit de créer la base de données dans un dossier. Ouvrir la commande mysql avec le bon utilisateur depuis le même dossier, et tu fais : Source nom_du_fichier.sql; Mais, tu peux lire le fichier, il est simple :

                  /* commentaire
                  multi ligne
                  */
                  
                  /* La condition IF NOT EXISTS permet de ne pas reconstruire les tables si ce fichier est exécuté plusieurs fois */
                  CREATE TABLE IF NOT EXISTS Produit (
                    id_produit smallint unsigned auto_increment,
                    nom_produit varchar(128) NOT NULL,
                    PRIMARY KEY (id_produit)
                  );
                  
                  CREATE TABLE IF NOT EXISTS Catégorie (
                    id_catégorie smallint unsigned auto_increment,
                    nom_catégorie varchar(128) NOT NULL UNIQUE,
                    PRIMARY KEY (id_catégorie)
                  );
                  
                  CREATE TABLE IF NOT EXISTS Origine (
                    id_origine smallint unsigned auto_increment,
                    ville_origine varchar(128) NOT NULL UNIQUE,
                    PRIMARY KEY (id_origine)
                  );
                  
                  CREATE TABLE IF NOT EXISTS Provenir (
                    produit smallint unsigned,
                    catégorie smallint unsigned,
                    origine smallint unsigned,
                    FOREIGN KEY (produit) REFERENCES Produit(id_produit),
                    FOREIGN KEY (catégorie) REFERENCES Catégorie(id_catégorie),
                    FOREIGN KEY (origine) REFERENCES Origine(id_origine),
                    PRIMARY KEY (produit, catégorie, origine)
                  );
                  
                  INSERT INTO Produit (nom_produit)
                  VALUES
                  ('lasagne_salade');
                  
                  INSERT INTO Catégorie (nom_catégorie)
                  VALUES
                  ('lasagne'),
                  ('salade');
                  
                  INSERT INTO Origine (ville_origine)
                  VALUES
                  ('Paris'),
                  ('Marseille');
                  
                  INSERT INTO Provenir(produit, catégorie, origine)
                  VALUES
                  (1, 1, 1),
                  (1, 2, 2);
                  
                  /* suppression des doublons en cas d'exécution multiple de ce fichier */
                  
                  Delete From Produit Where id_produit > 1;
                  Delete From Catégorie Where id_catégorie > 2;
                  Delete From Origine Where id_origine > 2;
                  
                  /* Pour répondre à la question :
                  Quand je fait un SELECT sur un de mes produits, comment savoir de quel type il est ? */
                  Select nom_produit, nom_catégorie From Produit Join Catégorie
                  Where nom_produit like 'lasagne_salade';
                  
                  /* et avec une requête préparée : */
                  SET @produit = 'lasagne_salade';
                  PREPARE lister_catégories FROM
                  'Select nom_produit, nom_catégorie From Produit Join Catégorie
                  Where nom_produit like ?';
                  EXECUTE lister_catégories USING @produit;
                  
                  /* J'ai attribué la valeur 'lasagne_salade' à la variable @produit,
                  j'ai préparé la requête en remplaçant 'lasagne_salade' par ?;
                  Lors de l'exécution, il suffit de faire correspondre le ? avec la variable @produit grâce au mot clé Using
                  (ce n'est pas le cas ici, mais, on peut avoir plusieurs ? et plusieurs variables utilisées avec using) */



                  -
                  Edité par CristianoRolando 25 janvier 2022 à 3:32:20

                  • Partager sur Facebook
                  • Partager sur Twitter

                  L'héritage et les requêtes

                  × 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