Partage
  • Partager sur Facebook
  • Partager sur Twitter

[MySQL][InnoDB] Contraintes sur deux champs entre deux table

    20 juin 2011 à 9:28:07

    Bonjour,

    J'ai une table "produit" définit comme ceci :

    pid UNSIGNED SMALL INT, NOT NULL 
    nom VARCHAR(125)
    


    J'ai définis une clé primaire sur le couple (pid, nom).

    J'ai une autre table utilisateur_log_play définit comme ceci :

    uid UNSIGNED MEDIUM INT, NOT NULL 
    pid UNSIGNED SMALL INT
    pnom VARCHAR(125)
    


    uid possède un index et une contrainte sur une table utilisateur (non décrite ici), jusque là pas de soucis.

    Je voudrais par contre lier les champs pid et pnom de la table utilisateur_log_play a ceux de la table produit, j'aimerais mettre comme contrainte sur le champ pid (ON DELETE SET NULL et ON UPDATE CASCADE) et sur le champ pnom (ON DELETE NO ACTION et ON UPDATE CASCADE)

    En gros, si on modifie l'id ou le nom d'un produit, la table utilisateur_log_play est mis à jour, si on supprime un produit seul la reference pid est mis à zero, on ne change pas pnom.

    Est-ce possible ? Comment ?

    Merci beaucoup.
    Cordialement ;)
    • Partager sur Facebook
    • Partager sur Twitter
      20 juin 2011 à 9:30:31

      Pourquoi faire la clé sur pid ET nom, au lieu de juste pid ???
      • Partager sur Facebook
      • Partager sur Twitter
        20 juin 2011 à 10:12:33

        Oui je pourrais le faire juste sur pid pas de soucis, mais il me faut une clé sur nom aussi, sinon pas de relation :/
        • Partager sur Facebook
        • Partager sur Twitter
          20 juin 2011 à 10:13:50

          Mais pourquoi ??? Une relation entre produit.pid et utilisateur_log_play.pid suffit.
          • Partager sur Facebook
          • Partager sur Twitter
            20 juin 2011 à 10:21:21

            Non j'en veux une aussi sur nom mais que en modification.

            Cas concret : si je supprime un produit, je veux que dans la table de log le pid passe à 0 (je saurais donc que le produit n'existe plus) mais je veux conserver une trace de son nom.

            Par contre si je modifie le nom d'un produit existant je veux que dans la table de log, tous les noms se mettent à jour.

            Suis-je compréhensible ?

            Merci d'avance.
            • Partager sur Facebook
            • Partager sur Twitter
              20 juin 2011 à 10:24:51

              Mais aucun intérêt d'avoir le nom AUSSI dans la table de log... Tu vas chercher le nom dans produit si t'en as besoin, c'est tout.
              • Partager sur Facebook
              • Partager sur Twitter
                20 juin 2011 à 10:30:27

                Si l’intérêt réside dans le faite que même si le produit est delete je garde quelque part le nom que portait ce produit.

                Est-ce au moins possible ? J'aimerais ne pas avoir à recourir aux triggers
                • Partager sur Facebook
                • Partager sur Twitter
                  22 juin 2011 à 16:05:34

                  Exemple sous postgres mais ça devrait marcher en innodb aussi...

                  L'intérêt de la chose m'échappe, mais enfin.

                  test=> CREATE TABLE p( pid SERIAL PRIMARY KEY, pname TEXT NOT NULL );
                  NOTICE:  CREATE TABLE créera des séquences implicites « p_pid_seq » pour la colonne serial « p.pid »
                  NOTICE:  CREATE TABLE / PRIMARY KEY créera un index implicite « p_pkey » pour la table « p »
                  test=> CREATE TABLE l( pid INTEGER NULL REFERENCES p(pid) ON DELETE SET NULL ON UPDATE CASCADE, pname TEXT NOT NULL );
                  CREATE TABLE
                  Temps : 187,085 ms
                  test=> ALTER TABLE p ADD UNIQUE( pid, pname );
                  NOTICE:  ALTER TABLE / ADD UNIQUE créera un index implicite « p_pid_key » pour la table « p »
                  test=> ALTER TABLE l ADD CONSTRAINT lp FOREIGN KEY (pid,pname) REFERENCES p(pid,pname) ON UPDATE CASCADE ON DELETE NO ACTION;
                  test=> INSERT INTO p (pname) VALUES ('a'),('b');
                  test=> INSERT INTO l SELECT * FROM p;
                  test=> select * from l;
                   pid | pname 
                  -----+-------
                     1 | a
                     2 | b
                  (2 lignes)
                  
                  test=> delete from p where pid=1;
                  DELETE 1
                  test=> select * from l;
                    pid   | pname 
                  --------+-------
                        2 | b
                   (NULL) | a
                  (2 lignes)
                  
                  test=> update p set pname='popo';
                  UPDATE 1
                  Temps : 0,536 ms
                  test=> select * from l;
                    pid   | pname 
                  --------+-------
                   (NULL) | a
                        2 | popo
                  (2 lignes)
                  
                  • Partager sur Facebook
                  • Partager sur Twitter

                  [MySQL][InnoDB] Contraintes sur deux champs entre deux 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