Partage
  • Partager sur Facebook
  • Partager sur Twitter

conseil construction table

Sujet résolu
    22 mars 2019 à 15:16:18

    Bonjour, 

    je vais rentrer directement dans le vif du sujet:

    J'ai créé deux tables: 1 table_professeur + 1 table_élève. 

    Je sais que le premier conseil est de faire une table et de mettre un rôle,

    mais je m'y suis senti contraint, puisque par la suite je crée deux tables qui ont comme FK l'id de l'utilisateur.

    1 table_cours_créé (fk id_professeur) + 1 table_cours_suivi (fk id_eleve). 

    Aujourdh'ui mon problème serait d'avoir un enregistrement des mails unique dans les deus tables 

    c'est à dire que le même mail ne peut pas se retrouver dans la table_élève et dans la table_professeur.

    Donc 1èrement faire en sorte que l'unicité existe. 

    2 èment lors d'un insert de compte me retourner le si tout c'est bien passé ou le code erreur

    3 èment me suggérer une autre architecture si 1 et 2 sont impossible . 

    j'ai beau réfléchir je n'en vois pas 

    j'ai fait ça mais,

    if($_POST['compte'] == '1'){
        $sql = 'INSERT INTO tb_professeurs (identifiant, mail, phone, password, clef) VALUE (:identifiant, :mail, :phone, :password, :cle)';
    } else {
        $sql = 'INSERT INTO tb_eleve (identifiant, mail, phone, password, clef) VALUE (:identifiant, :mail, :phone, :password, :cle)';
    }
     
    try{
        // Insertion de la clé dans la base de données (à adapter en INSERT si besoin)
    $req = $bdd->prepare($sql);
    $req->bindParam(':cle', $cle);
    $req->bindParam(':identifiant', $pseudo);
    $req->bindParam(':mail', $email);
    $req->bindParam(':phone', $phone);
    $req->bindParam(':password', $password);
    $req->execute();
    }catch (PDOException $e){
        die('erreur : '.$e ->getMessage());
    }



    il y a mieux ?

    -
    Edité par born1 22 mars 2019 à 15:19:50

    • Partager sur Facebook
    • Partager sur Twitter
      22 mars 2019 à 15:38:53

      Bonjour,

      Je vois deux possibilité, sois faire la vérification (en php par exemple), en requetant et en voyant si le mail existe d'un coté ou de l'autre.

      Soit en sql directement avec des triggers

      • Partager sur Facebook
      • Partager sur Twitter
        22 mars 2019 à 16:38:43

        Bonjour,

        born1 a écrit:

        Je sais que le premier conseil est de faire une table et de mettre un rôle,

        mais je m'y suis senti contraint, puisque par la suite je crée deux tables qui ont comme FK l'id de l'utilisateur

        Ce n'est pas une raison ... Si les attributs qualifiant un élève et un professeur sont exactement les mêmes, il ne faut justement pas éclater l'entité en deux ... Rien ne t'empêche de faire deux clés étrangères dans la même table vers la même référence ...

        Le modèle le plus simple :

        • personne ( id_personne [pk], nom, prenom, email [unique], role )
        • cours ( id_cours [pk], intitule, id_professeur [fk] )
        • eleve_cours ( id_cours [pk][fk], id_eleve [pk][fk] )

        Une contrainte UNIQUE sur la colonne email, et une colonne role en CHAR(1) valant E ou P selon ...

        Il faut par contre mettre en place un TRIGGER empêchant de rattacher à un cours un id_personne qui n'est pas professeur, et faire suivre un cours à un id_personne qui n'est pas élève ...

        Si les attributs sont différents entre professeur et élève, alors il faut utiliser la notion d'héritage :

        • personne ( id_personne [pk], nom, prenom, email [unique] )
        • eleve ( id_personne [pk], classe, option )
        • professeur ( id_personne [pk], specialite, diplome )
        • cours ( id_cours [pk], intitule, id_professeur [fk] )
        • eleve_cours ( id_cours [pk][fk], id_eleve [pk][fk] )

        C'est un peu plus compliqué, mais cela assure l'intégrité directe de la base : unicité de l'email, et impossibilité de rattacher un élève à un cours et de faire suivre un cours à un professeur.

        • Partager sur Facebook
        • Partager sur Twitter
        Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
          25 mars 2019 à 23:49:58

          Bonjour,

          Pour ce que tu cherches à faire je t'avais donné 2 solutions plus rigoureuses : https://openclassrooms.com/forum/sujet/conseil-construction-table?page=1#message-93050842

          Mais tu n'avais pas répondu et tu as persisté sur une solution moins normalisée et donc plus problématique ...

          Je renouvelle donc mes 2 propositions : avec une colonne rôle ou avec une notion d'héritage ...

          Si tu veux persister, alors tu auras en effet besoin des TRIGGER ...

          'Ce n'est pas que j'ai persisté, au contraire, j'ai étudié la possibilité d'héritage, mais il m' semblé qu'une colonne ne pouvait être la FK qu'une fois sinon, il y avait une erreur de doublon. Mais je vois que j'ai mélangé les erreurs (dsl)

          Alors j'ai créé une simple table personne (id_personne, nom, prenom, mdp, role)

          puis un table professeur (id_professeur, id_personne)

          pour avoir une table cours (id_cours, id_professeur, cours)

          maintenant, je voudrais que la table professeur soit rempli seul donc, une sorte de requête comme :

          INSERT INTO table_personne(col1, col2, col3) VALUES (val1, val2, val3) UPDATE table_professeur

          Sinon, je me demandais si je crée une table élève (id_élève[PK], nom, prénom,mail, mdp, role) + une table professeur (id_prof[PK], nom, prénom, mail[unique], mdp, role) et que je crée une table utilisateur avec (id_utilisateur[PK], mail[FK,unique], mdp)

          avec des FK delete & update en cascade, ça marchera? les mails seront unique dans les deux tables?

          (La différence serait que la table utilisateur s'incrément après les tables professeur & élève.)

          -
          Edité par born1 26 mars 2019 à 12:31:01

          • Partager sur Facebook
          • Partager sur Twitter
            26 mars 2019 à 12:01:39

            Tu n'as pas bien compris ma proposition précédente.

            Dans les deux solutions proposées aucune ne correspond à celle que tu essayes de mettre en oeuvre ... tu as fais un espèce de mixte des deux :D

            Commence par répondre à la question :

            Benzouye a écrit:

            les attributs sont-ils différents entre professeur et élève

            Si oui alors héritage, si non alors colonne "rôle" et TRIGGER.

            • Partager sur Facebook
            • Partager sur Twitter
            Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
              27 mars 2019 à 12:40:41

              Bon ben ok je vais voir comment fonctionne l'héritage en MySQL, UN TRIGGER pardon*!

              -
              Edité par born1 27 mars 2019 à 23:52:48

              • Partager sur Facebook
              • Partager sur Twitter
                27 mars 2019 à 13:15:11

                born1 a écrit:

                une table élève (id_élève[PK], nom, prénom,mail, mdp, role) + une table professeur (id_prof[PK], nom, prénom, mail[unique], mdp, role) et que je crée une table utilisateur avec (id_utilisateur[PK], mail[FK,unique], mdp)

                Dans cet exemple, eleve et professeur ont les mêmes attributs ... Donc :

                Benzouye a écrit:

                • personne ( id_personne [pk], nom, prenom, email [unique], role )
                • cours ( id_cours [pk], intitule, id_professeur [fk] )
                • eleve_cours ( id_cours [pk][fk], id_eleve [pk][fk] )

                Une contrainte UNIQUE sur la colonne email, et une colonne role en CHAR(1) valant E ou P selon ...

                Il faut par contre mettre en place un TRIGGER empêchant de rattacher à un cours un id_personne qui n'est pas professeur, et faire suivre un cours à un id_personne qui n'est pas élève ...

                Si c'est une erreur de ta part et que professeur et élève ont des attributs différents, alors : https://sqlpro.developpez.com/cours/modelisation/heritage/

                Benzouye a écrit:

                Si les attributs sont différents entre professeur et élève, alors il faut utiliser la notion d'héritage :

                • personne ( id_personne [pk], nom, prenom, email [unique] )
                • eleve ( id_personne [pk], classe, option )
                • professeur ( id_personne [pk], specialite, diplome )
                • cours ( id_cours [pk], intitule, id_professeur [fk] )
                • eleve_cours ( id_cours [pk][fk], id_eleve [pk][fk] )

                C'est un peu plus compliqué, mais cela assure l'intégrité directe de la base : unicité de l'email, et impossibilité de rattacher un élève à un cours et de faire suivre un cours à un professeur.





                -
                Edité par Benzouye 27 mars 2019 à 13:18:47

                • Partager sur Facebook
                • Partager sur Twitter
                Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
                  28 mars 2019 à 1:48:55

                  ok merci BENZOUYE, j'ai compris à quoi, et pourquoi l'utiliser, mais le cours, ne permet pas d'écrire la syntaxe correct pour mon cas, 

                  peux-tu m'éclairer ? 

                  j'ai rédiger ce code sans conviction:

                  CREATE TRIGGER before_insert_folder BEFORE INSERT ON tb_classeurs BEGIN IF tb_users.compte = 1 WHERE id_pro = tb_users.id_user

                  et comme je le pensais, ça n'a pas fonctionner, 

                  MySQL à répondu:
                  #1064 - Erreur de syntaxe près de 'BEGIN IF tb_users.compte = 1 WHERE id_pro = tb_users.id_user' à la ligne 1

                  • Partager sur Facebook
                  • Partager sur Twitter
                    28 mars 2019 à 8:55:40

                    Si tu pars sur un TRIGGER c'est que ne devrait avoir qu'une seule table personne avec une colonne "rôle". C'est bien le cas ?

                    Peux-tu poster la structure actuelle de ta base (tables, colonnes, types, clés, contraintes) histoire de voir ce que tu as fais ?

                    Sinon la syntaxe du TRIGGER n'est vraiment pas celle du cours, donc en effet MySQL lève un erreur ... je te conseille de bien relire le cours où tout est présent pour t'aider. On fignolera ensemble ici ;)

                    • Partager sur Facebook
                    • Partager sur Twitter
                    Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
                      28 mars 2019 à 14:00:19

                      Je n'en verrai pas de photo de la BDD, car il reste encore des traces de l'ancienne structure: 

                      Sinon la structure 

                      tb_users: ID_user(AI), lastname(varchar255), firstname(varchar255), identifiant(varchar20; unique), mail(varchar255, unique), password(varchar255), phone(int10), role(int11), clef(varchar32), actif(int11).

                      tb_cours: ID_cours(AI), ID_user(FK), titre(varchar50), cours(text), matière(varchar20), date(date),

                      classeurs: ID_cours_suivi(AI), ID_cours(FK), ID_user(FK)

                      Alors bien sur, il n'y a que les professeurs (role = 1) qui peuvent créer des cours, et que des élèves (role = 0), qui peuvent rajouter des cours à leur classeur. 

                      Je répond hâtivement , 

                      mais la requête serait: 

                      DELIMITER |
                      CREATE TRIGGER before_inser_classeur BEFORE INSERT ON classeurs
                      BEGIN 
                      DECLARE compte INT(11);
                      SELECT role INTO compte FROM tb_users WHERE ID_user = NEW.id_eleve; 
                      IF compte = 0 
                      THEN INSERT INTO classeurs (ID_cours, ID_user) VALUES (NEW.ID_cours, NEW.ID_eleve);
                      END IF;
                      END |
                      DELIMITER;

                      ou même 

                      DELIMITER |
                      CREATE TRIGGER before_inser_classeur BEFORE INSERT ON classeurs
                      BEGIN 
                      DECLARE compte INT(11);
                      SET compte = SELECT role FROM tb_users WHERE ID_user = NEW.id_eleve; 
                      IF compte = 0 
                      THEN INSERT INTO classeurs (ID_cours, ID_user) VALUES (NEW.ID_cours, NEW.ID_eleve);
                      END IF;
                      END |
                      DELIMITER;
                      • Partager sur Facebook
                      • Partager sur Twitter
                        28 mars 2019 à 15:58:27

                        born1 a écrit:

                        classeurs: ID_cours_suivi(AI), ID_cours(FK), ID_user(FK)

                        Dans cette table la clé primaire devrait simplement être une clé primaire composite : PRIMARY KEY ( ID_cours, ID_user ). Pas besoin de créer un auto-incrément qui est inutile et prend de la place pour rien ...

                        Concernant les TRIGGER ce n'est toujours pas bon, et tu vas avoir des erreurs à l'exécution, principalement parce que tu ne pas utiliser au sein du TRIGGER la table sur laquelle est placé le TRIGGER.

                        La logique est toutefois presque bonne, sauf qu'au lieu d'exécuter un insert si le rôle est bon, c'est plutôt qu'il faut lever une erreur (SIGNAL) si le rôle n'est pas bon.

                        Et il manque aussi le FOR EACH ROW ;)

                        DELIMITER |
                        CREATE TRIGGER before_inser_classeur
                        BEFORE INSERT ON classeurs
                        FOR EACH ROW
                        BEGIN
                        	DECLARE compte INT(11);
                        	SELECT role INTO compte FROM tb_users WHERE ID_user = NEW.id_eleve;
                        	
                        	IF compte <> 0 THEN
                        		SIGNAL SQLSTATE '23000'
                        			SET MESSAGE_TEXT = 'Seul les élèves peuvent être liés à un cours';
                        	END IF;
                        END |
                        DELIMITER;

                        Ainsi, si le rôle n'est pas bon, une erreur est levée et l'insert n'est pas exécuté. A toi de traiter cette erreur côté code pour afficher ce qu'il faut dans ton application.

                        • Partager sur Facebook
                        • Partager sur Twitter
                        Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
                          28 mars 2019 à 21:32:29

                          Alors Merci . 

                          MERCI MERCI MERCI !!!!!!!!!!!

                          Mille MerciSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS



                          Euh petite question, comment faire pour que cette association id_cours/id_élève  n'existe qu'une seule fois, un trigger ne pouvant lire la table sur laquelle il est 

                          -
                          Edité par born1 28 mars 2019 à 21:48:21

                          • Partager sur Facebook
                          • Partager sur Twitter
                            28 mars 2019 à 23:15:27

                            C'est le rôle de la clé primaire composite...

                            Il est temps de te former quand même...

                            • Partager sur Facebook
                            • Partager sur Twitter
                            Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
                              29 mars 2019 à 0:05:22

                              ok ok je n'avais jamais eu besoin jusque là de plus , d'ailleurs dans ma formation on à vu moins que le strict minimum je pense. 

                              merci pour ta réponse, je m'y intéresse de suite

                              En plus c'est tout con, mais je n'avais vu que le fonctionnement permettait cela! 

                              -
                              Edité par born1 29 mars 2019 à 0:24:43

                              • Partager sur Facebook
                              • Partager sur Twitter

                              conseil construction table

                              × 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