sujet délicat: auto incrément

page 1 page 2 page 3
Répondre
Necnom
Necnom
Déconnecté
Necnom :)
Bonjour, j'ai envie de reparler d'un sujet délicat puisque j'ai déjà remarqué que cette question chamboule les programmeurs "haut niveau".
Beaucoup se demandent comment faire pour qu'il n'y ait pas de trou dans le champs auto incrémenté, lorsque l'on supprime un élément d'une table.
Par exemple, certains utilisent la table suivante:
-------------------------
1- Lucas - seconde 8
2- Corinne - première L 3
4- Lucien - Terminale ES 1
-------------------------
Vous remarquez que la suppression d'un candidat ( le 3 ) ne reclasse pas l'auto incrément.

Donc les réponses sont souvent, "tu n'as pas compris le principe de l'auto incrément", "non, tu ne peux pas revaloriser ton auto incrément, ce n'est pas le but, tu n'as pas compris blablabla ..."
Certe, ce n'est pas peut-être pas l'objectif de l'auto incrément, mais ceci peut s'avérer quand même utile et je ne vois pourquoi autant critiquer ceux qui demandent et qui cherchent à enlever les trous.
----------------------------


Ps: je parlais des lieux de discussion en général smiley
Koboneil
Koboneil
Déconnecté
Koboneil
Je n'ai pas une grande expérience dans les bases de données, mais je ne vois pas en quoi ça peut être utile de faire cela. As tu des exemples à nous donner ?
De plus, j'ai rarement vu l'auto_increment utilisé sur autre chose que des clefs primaires (là encore si quelqu'un a des exemples...). Dans ce cas, ça serait vraiment dingue de vouloir combler les "trous" sachant que cette clef peut se retrouver clef étrangère dans d'autres tables de ta base de données.
LA GLOBULE
LA GLOBULE
Déconnecté
111 111 111 x 111 111 111 = 12 345 678 987 654 321
La remarque de koboneil est bonne. Mais bon, rien n'empèche de faire un script qui modifie aussi les clés étrangères des autres tables (ca se fait facilement avec un trigger voir des contraintes de clefs étrangères).

Je vois une seconde remarque : le référencement.

En effet, les clefs primaires (qui sont souvent des AUTO_INCREMENT) apparaissent dans les URL des pages web (typiquement, la page que tu regardes en ce moment, tu verras l'id de ce sujet de forum dans l'URL). Cette page va donc se faire indexer avec l'id 5450. Imaginons qu'un autre site link cette page. Si je supprime cet id et que je crée un autre sujet avec le même id, le backlink me fera arriver sur une page qui n'a rien à voir avec le sujet de départ. Alors que si j'ai un trou dans mes id, ca fera une 404, et la, c'est clair pour tout le monde.

Et sinon, une troisième remarque : que de boulot pour pas grand chose :)
i M@N
i M@N
Déconnecté
One Love, One Heart, One Unity.
Hello.

C'est clair ça sert pas à grand chose ... c'est limite un T.O.C de vouloir remettre des champs autoincrémentés les uns à la suite des autres ... smiley

@+...
Necnom
Necnom
Déconnecté
Necnom :)
Mais si quelqu'un désire faire un classement.
Par exemple la liste des élèves d'une classe. Chaque jour ça change, et chaque élève a une position. Le dernier élève à la position 34.
Un nouveau s'inscrit et a donc la position 35 ( auto incrément).
Et lorsqu'un élève démissionne ou part ou est viré, une réorganisation s'effectue. Si l'élève avait la position 23, celui qui avait la position 24 prend sa place, celui qui avait la position 25 prend la 24, la 26 devient 25 etc ...
Donc selon vous, il faudrait carément créer un autre champs ...
Necnom
Necnom
Déconnecté
Necnom :)
désolé ... j'ai cliqué malencontreusement sur envoyer; je continue .

Aussi, je ne vois pas comment mettre plusieurs auto incréments sur la même table, enfin .. pour moi je n'y arrive pas. C'est pour ça que je pense qu'une revalorisation d'un auto incrément n'aurait pu être qu'utile.

Dans notre exemple, après le départ du numéro 23, le nouvel inscrit aurait pris encore la position 35, et non 36 ou 37 etc ...
LA GLOBULE
LA GLOBULE
Déconnecté
111 111 111 x 111 111 111 = 12 345 678 987 654 321
Moi oui, j'ajouterais un champ 'position' que je recalculerais. L'étudiant aurait toujours le même identifiant.

Le champs AUTO_INCREMENT est un faux ami : c'est pratique, ca génère des identifiants uniques, mais les gens veulent s'en servir dans un but de "présentation". Or ce n'est pas fait pour.

Imagine que l'AUTO_INCREMENT n'existe pas (typiquement en SyBase, pas d'AUTO_INCREMENT), tu les geres comment tes id / position ? Ben tu crées des clés sur les noms des étudiants, et la aussi, tu es obligé d'avoir un champ 'position'.

PS : il existe des trix pour gérer des AUTO_INCREMENT en SyBase => créer une table qui contient un seul élément : la valeur du dernier id généré que l'on incrémente à chaque fois que l'on veut générer un id.
Necnom
Necnom
Déconnecté
Necnom :)
Le champs AUTO_INCREMENT est un faux ami : c'est pratique, ca génère des identifiants uniques, mais les gens veulent s'en servir dans un but de "présentation". Or ce n'est pas fait pour.

Dans ce cas, existe-t-il ou il y a t-il une possibilité pour avoir 2 champs auto incrémentés dont, le premier serait l'id gardé définitivement par l'étudiant, et le second la position, tout ceci dans une base normale, et dans la même table.
Parce que si il faut choisir entre 1 auto incrément modifiable et la création d'un autre champs ou d'une autre table avec un script pour gérer les positions par exemple, j'avoue que le côté pratique de la chose n'est pas là .
LA GLOBULE
LA GLOBULE
Déconnecté
111 111 111 x 111 111 111 = 12 345 678 987 654 321
Non, çà n'existe pas, et tu aurais le même problème : à chaque suppression, tu devras recalculer toutes les positions.
De toutes facons, MySQL ne les recalculera jamais pas pour toi (sauf procédure stockée, trigger : ce sont des trucs que tu dois écrire, c'est pas automatique), donc autant le faire avec du PHP.
Lefounard
Lefounard
Déconnecté
I am singing in the rain , I am happy again !!
Les programmeurs haut niveau n'utilise pas un id comme clé, ils font des clés a partir de couple de 1 a n champs.
J'ai vu ca durant mes cours de bd, et ma prof n'arrete pas de le repeter.
Mais comme fait la plupart des gens sur par exemple MySQL, un champs id avec un attribut auto-increment c'est pas "popre".
zebden
zebden
Déconnecté
zebdinou pour les intimes / Blog : http://www.zebden.fr
Mouais, une clef doit être une donnée abstraite qui n'a rien à voir avec le contenu de la table pour relier des tables ou distinguer les données (grossièrement).

Après, tu as plusieurs solutions pour générer ta clef. Mais coupler plusieurs champs, non pas besoin.
Lefounard
Lefounard
Déconnecté
I am singing in the rain , I am happy again !!
Pourtant une clé, se calcule grace aux dépendances fonctionnelles.
C'est la théorie des ensembles.
Apres, c'est vrai que je suis plus dans le monde la théorie.
Surement qu'en pratique , c'est plus judicieux et performant d'utiliser un id comme clé, mais en tout cas, sur Oracle, en cours, on nous fesait prendre comme clé generalement des couples.
zebden
zebden
Déconnecté
zebdinou pour les intimes / Blog : http://www.zebden.fr
Tout dépends du contexte surement. Mais des fois, faut pas trop se compliquer la vie.
Necnom
Necnom
Déconnecté
Necnom :)
Si toute fois il faullait reclasser un champs. Est-ce que le code que je propose serait correct ?

index.php
  1.  
  2. <?php
  3. // Il nous faut trouver le nombre d'informations enregistrées dans la base de données  
  4. // requête sql  
  5. $sql='SELECT id, position FROM ma_table';  
  6. $req = mysql_query($sql) or die('Erreur SQL !<br />'.$sql.'<br />'.mysql_error());  
  7. // on compte et le nombre trouvé doit être le nombre maximal dans le champs position. Si il y a 26 données, il y a donc 26 positions et la positions de la dernière données est 26  
  8. $nb_max = mysql_num_rows($req);  
  9. // remarquons que l'on part du principe où le champs position a pour première valeur 1.  
  10. // on vérifie donnée par donnée que tout est dans l'ordre et qu'il n'y ait pas de trous.  
  11. $nb_fetch = "1";  
  12. while ($data = mysql_fetch_array($req)) {  
  13. $data['id'] = $id; // on a simplifié la variable  
  14.  
  15. if ( $data['position'] <= $nb_max ) {  
  16. // on vérifie que la position est bien celle qu'il faut si non, on la change  
  17. if ( $data['position'] != $nb_fetch ) {  
  18. sql2='UPDATE ma_table SET position="'.$nb_fetch.'" WHERE id="'.$id.'"';  
  19. // on exécute la requête (mysql_query) et on affiche un message au cas où la requête ne se passait pas bien (or die) ^^  
  20. mysql_query($sql2) or die('Erreur SQL pour une reclassification !'.$sql2.'<br />'.mysql_error());  
  21.  
  22. }  
  23.  
  24. }  
  25. // on n'oublie pas après d'augmenter la valeur de $nb_fetch si non, toutes les positions seraient de 1  
  26. $nb_fetch = $nb_fetch + 1;  
  27. // on termine le reclassement  
  28. if ( $data['position'] > $nb_max ) {  
  29. mysql_close ();  
  30. echo'Le reclassement des positions est effectué!';  
  31. }  
  32. }  
  33.  
  34. ?>
  35.  


On admet qu'il n'y a pas de position 0, et qu'il ne peut y avoir deux mêmes positions.
On peut placer ce code après chaque insertion si le champs position n'est pas auto incrémenté ( quoique, même quand c'est auto-incrémenté ...), ou après chaque suppression.

Vous pouvez me donner votre avis s.v.p ?
Necnom
Necnom
Déconnecté
Necnom :)
Il y a aussi une autre solution qui consisterait à faire une selection des informations par requête. Et comme il est possible de classer les informations dans l'ordre croissant, on le fait et on les insère une par une dans un champs vide. Mais bon. Ce n'est pas automatique.
page 1 page 2 page 3
Répondre
Accès rapide :

Remonter Remonter
L'éditeur javascript - CSS - Gentoo - Tutoriaux PHP - Tutoriels PHP - Breizh Blog