Partage
  • Partager sur Facebook
  • Partager sur Twitter

Empêcher des "trous" dans le champ id

après un effacement...

Sujet résolu
    1 décembre 2010 à 6:02:25


    Bonjour,

    Ça me simplifierait la vie de savoir comment faire en sorte que les id se suivent sans "trous" dans ma table même après un effacement.

    Si j'ai :
    1, 2, 3, 4, 5, 6

    Voici ce qui se passes si j'efface le cinquième élément de ma table :
    1, 2, 3, 4, 6

    Alors que je voudrais obtenir ça :
    1, 2, 3, 4, 5

    Ça peut paraître idiot comme besoin, mais pour l'archivage de message, c'est bien :)

    Il doit bien y avoir quelque chose de prévu pour faire ça à la volée mais c'est assez difficile à formuler quand on ne connait pas les termes adéquats et donc de trouver sur le net.

    Merci à vous !
    • Partager sur Facebook
    • Partager sur Twitter
      1 décembre 2010 à 7:51:06

      Tu risques juste d'introduire des erreurs dans ta table. JE ne comprends pas pourquoi tu en as besoin, mais si tu y tiens absolument, alors je te conseille d'ajouter un champ à ta table, sans auto-incrément, où tu le fais toi-même.
      • Partager sur Facebook
      • Partager sur Twitter
        1 décembre 2010 à 8:00:22

        bonjour,
        id ne veut pas dire id auto-incrémenté.
        Avec Oracle et ses séquences impossible de remplir les trous sauf à écrire ton algo pour trouver les trous.
        Avec MySQL (testé avec la 5.1) si tu as un id auto_increment, c'est pareil.
        Tu écris ton ordre INSERT en précisant la valeur de la clé.
        Exemple :
        CREATE TABLE  trous (
          id int(10) unsigned NOT NULL AUTO_INCREMENT,
          nom varchar(45) NOT NULL,
          PRIMARY KEY (id)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
        

        Ensuite tu insères 3 enregistrements puis tu supprimes le 2.
        Enfin tu "recrées" le 2 ainsi :
        INSERT INTO trous (id,nom) VALUES(2,'bbb');
        
        • Partager sur Facebook
        • Partager sur Twitter
          1 décembre 2010 à 8:54:33

          Au-delà de toute considération technique :

          Un ID est un champ technique qui ne doit servir qu'à identifier une ligne de manière unique. Il ne sert qu'à ça et à rien d'autre.

          En particulier, un ID ne sert pas à :
          • Compter des lignes.
          • Ordonner des lignes.

          Conséquence : ça ne change rien qu'il y aie des trous ou pas dans la séquence de ton ID. Ton application doit pouvoir fonctionner si quand tu insères successivement trois lignes, tu te retrouves (dans l'ordre) avec 1, 25475 et 542 comme IDs pour ces lignes.

          Un ID ne change jamais et n'est jamais réutilisé.
          Si j'ai les lignes 1, 2 et 3 et que je supprime la 2, la ligne 3 reste la ligne 3. point final.
          Idem si je rajoute un nouveau champ : celui-ci ne doit pas devenir le champ 2, parce que ça entrainerait confusion donc bugs avec l'ancienne ligne 2.


          Donc, si tu essaie d'éviter les trous dans ton ID, c'est que tu te sers de ton ID à mauvais escient.
          Comment as-tu prévu ton "archivage de messages" pour avoir besoin d'une séquence continue comme IDs ?
          • Partager sur Facebook
          • Partager sur Twitter
            1 décembre 2010 à 14:34:12

            Vous êtes bien matinaux !

            Merci pour toutes vos interventions et vos conseils, je comprends mon erreur.

            Spacefox > J'ai un menu qui offre une vue dans laquelle un clic sur l'extrait d'un titre nous amène directement à l'un des messages adjacents (+ ou - 15 messages). Et du coup je me servais de l'id pour pointer sur mon message... et même pour les compter :waw: Alors forcément il y avait des ratés...

            Puni !

            Je croyais que c'était mieux que d'avoir trop de champs dans une table mais je me rends compte de mon erreur.

            Donc je vais ajouter un champ int à la table des messages que j'incrémenterai manuellement à chaque ajout de message. Et dans le cas d'un effacement je lance un script qui réajuste la séquence pour éviter les trous. Et je m'en servirai pour pointer sur les messages. Il faut juste que je m'assure que l'effacement d'un message par l'un ne vienne pas chambouler l'activité en cours d'un autre...

            C'est mieux ?

            P. S. : dans mon précédent message j'ai utilisé le terme archivage au lieu de présentation des messages, autant pour je.
            • Partager sur Facebook
            • Partager sur Twitter
              1 décembre 2010 à 18:25:09

              Si l'id provient d'une séquence ou d'un auto-increment, on peut tout à fait l'utiliser pour le tri, c'est d'ailleurs recommandé et pratique.

              > un clic sur l'extrait d'un titre nous amène directement
              > à l'un des messages adjacents (+ ou - 15 messages)

              Et tu n'as pas envie de faire :

              SELECT * FROM messages WHERE thread=blabla AND id <= $id ORDER BY id DESC LIMIT 16
              SELECT * FROM messages WHERE thread=blabla AND id > $id ORDER BY id LIMIT 15
              


              ?
              • Partager sur Facebook
              • Partager sur Twitter
                1 décembre 2010 à 19:11:35

                Lord Casque Noir >

                J'ai bien commencé avec cette approche mais ça ne fonctionne pas. Je voudrais que le raccourci vers le message courant s'affiche au milieu de la liste descendante, or là on a un coup une liste qui descend puis après qui monte... ce qui n'est pas cohérent bien que tous les éléments sont là.

                Donc je verrais plutôt un truc de genre :

                D'abord je crée un champ "rang" dans ma table puis :
                <?php
                ...
                if ($rang_courant > 15)
                $rang_depart = $rang_courant - 15;
                else
                $rang_depart = 0;
                $sql = 'SELECT * FROM messages WHERE rang >= $rang_depart ORDER BY id DESC LIMIT 30';
                ...
                ?>
                


                J'essaie de suite :)
                • Partager sur Facebook
                • Partager sur Twitter
                  1 décembre 2010 à 19:24:30

                  Citation : Ceriko

                  Je voudrais que le raccourci vers le message courant s'affiche au milieu de la liste descendante, or là on a un coup une liste qui descend puis après qui monte...



                  Tu as PHP d'installé, non ?

                  L'autre méthode est pénible à mettre en place si tu supprimes des messages parce qu'il faut mettre à jour le rang. D'ailleurs la requête serait dans ce cas :

                  SELECT * FROM messages WHERE rang BETWEEN $rang_depart-15 AND $rang_depart+15 ORDER BY rang';
                  


                  Mais fais-le avec la méthode standard, c'est beaucoup plus simple.
                  • Partager sur Facebook
                  • Partager sur Twitter
                    1 décembre 2010 à 20:06:24

                    Je trouve aussi que c'est mieux du coup mais je n'arrive pas à utiliser array_reverse(), même en lisant le manuel. Le code suivant ne fonctionne pas et PHP me dit :

                    Fatal error: Call to a member function fetch() on a non-object in ...


                    Donc je n'applique pas la fonction correctement et je ne vois pas du tout comment faire.

                    <?php
                    include ("mc_connection_bdd.php");
                    $sql = 'SELECT * FROM minichat WHERE id > ' . $id_courant . ' ORDER BY id LIMIT 15';
                    $req = $bdd->prepare($sql);
                    $req->execute();
                    $qer = array_reverse($req);
                    while ($data = $qer->fetch())
                    ...
                    ?>
                    

                    Remarquez que je suis quand même parvenu à faire un reverse sur le nom de la variable :-°

                    EDIT :

                    Ca fonctionne maintenant avec :

                    <?php
                    include ("mc_connection_bdd.php");
                    $sql = 'SELECT * FROM minichat WHERE id > ' . $id_courant . ' ORDER BY id LIMIT 15';
                    $req = $bdd->prepare($sql);
                    $req->execute();
                    while ($data = array_reverse($req->fetch()))
                    {
                    ?>
                    


                    Merci beaucoup à Lord Casque Noir et aux autres :)
                    • Partager sur Facebook
                    • Partager sur Twitter
                      1 décembre 2010 à 22:27:36

                      En fait pour inverser les résultats il faut ramener le jeu complet de résultat (toutes les lignes pas juste une, donc fetchAll et non fetch) ce qui te donne un tableau que tu peux ensuite inverser simplement :

                      <?
                      $sql = 'SELECT * FROM minichat WHERE id > ' . $id_courant . ' ORDER BY id LIMIT 15';
                      $req = $bdd->prepare($sql);
                      $req->execute();
                      foreach( array_reverse( $req->fetchAll()) as $data )
                      
                      • Partager sur Facebook
                      • Partager sur Twitter

                      Empêcher des "trous" dans le champ id

                      × 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