Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

SE PASSER DE L'AUTO INCRÉMENT


Information sur la source

Catégorie :Base de données Niveau : Débutant Date de création : 19/10/2004 Date de mise à jour : 19/10/2004 16:49:00 Vu : 2 453

Note :
6,83 / 10 - par 6 personnes
6,83 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

Commentaire sur cette source (14)
Ajouter un commentaire et/ou une note

Description

Cette fonction, très simple, permet d'avoir une suite de clés primaires continue, sans trou.
 

Source

  • /***************************************
  • ** Fonction getCode() **
  • **^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^**
  • ** Prend le premier code dispo **
  • ** dans la table passée en paramètre **
  • ***************************************/
  • function getCode($table){
  • //Si la table est vide, code=1
  • $sql='SELECT count(code) FROM '.$table;
  • $rst=mysql_query($sql);
  • $compteur=mysql_fetch_array($rst,MYSQL_ASSOC);
  • if ($compteur['count(code)']==0){
  • $unCode=1;
  • }
  • // Sinon, on cherche un trou
  • else{
  • $rst=mysql_query('SELECT code FROM '.$table.' ORDER BY code ASC') or die('impossible de récupérer les codes');
  • $i=1;
  • while($code = mysql_fetch_array($rst,MYSQL_ASSOC)){
  • if($code['code']==$i){
  • $i++;
  • }
  • else{
  • $unCode=$i;
  • }
  • }
  • }
  • //si on n'a pas trouvé de trou, on prend le plus petit code vide
  • if(empty($unCode)){
  • $rst=mysql_query('SELECT MAX(code) FROM '.$table) or die('echec de la requête');
  • $maxCode=mysql_fetch_array($rst,MYSQL_ASSOC);
  • $unCode = $maxCode['MAX(code)']+1;
  • }
  • return $unCode;
  • }
/***************************************
**	Fonction getCode()				**
**^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^**
**    Prend le premier code dispo			**
** dans la table passée en paramètre  **
***************************************/

function getCode($table){
	//Si la table est vide, code=1
	$sql='SELECT count(code) FROM '.$table;
	$rst=mysql_query($sql);
	$compteur=mysql_fetch_array($rst,MYSQL_ASSOC);
	if ($compteur['count(code)']==0){
		$unCode=1;
	}
	// Sinon, on cherche un trou
	else{
		$rst=mysql_query('SELECT code FROM '.$table.' ORDER BY code ASC') or die('impossible de récupérer les codes');
		$i=1;
		while($code = mysql_fetch_array($rst,MYSQL_ASSOC)){
			if($code['code']==$i){
				$i++;
			}
			else{
				$unCode=$i;
			}
		}
	}
	//si on n'a pas trouvé de trou, on prend le plus petit code vide
	if(empty($unCode)){
		$rst=mysql_query('SELECT MAX(code) FROM '.$table) or die('echec de la requête');
		$maxCode=mysql_fetch_array($rst,MYSQL_ASSOC);
		$unCode = $maxCode['MAX(code)']+1;
	}
	return $unCode;
}

Conclusion

L'auto incrément, c'est bien: Pas besoin de gérer les clés primaires, c'est la SGBD qui s'en occupe ...
Le problème c'est que quand on supprime un tuple, on a un trou
Par exemple
1  / martin
2 / Jean
3 / Paul
4 / Jacques

On supprime Paul et on ajoute Rémi

1  / martin
2 / Jean
4 / Jacques
5 / Rémi

On n'aura plus de tuple 3, et on perd une entrée dans la table. De quoi vite saturer une table si on fait beaucoup d'ajouts/suppression. (Bon c'est vrai, il faut vraiment en faire beaucoup)
Grâce à getCode,  le tuple entré sera 3 / Rémi on ne perd pas de place !

Note: Le tuple 0 ne sera jamais retourné, c'est volontaire.
Il pourra servir de tuple tampon (par exemple pour échanger deux clés primaires)

 

Historique

19 octobre 2004 16:49:00 :

Commentaires et avis

signaler à un administrateur
Commentaire de Magidev le 20/10/2004 01:40:26

Je ne vois pas vraiment l'utilité vu que le but de l'auto incrément permet d'avoir un numéro unique pour chaque enregistrement. Et rien ne "Sature" il suffit de choisir le format adapté a ton champ, comme INT, BIGINT etc.

De plus, pour les Bases de données Relationnelles cela peut poser probleme, et meme de sérieux

Imagine que on utilise ton principe pour des utilisateurs
dans un forum par exemple.

Après chaque message du forum on attache l'ID de la personne qu'il l'a postée.

ID---MESSAGE---AUTEUR
0     Test            1
1     Bonjour       2
2     Test            3

A partir de la, l'administrateur décide de supprimer le compte de l'utilisateur 3, mais il ne va pas vider tout ses messages du forum car ils sont interessant pour la plus part

Quand on consultera un message, et que l'on voudra récupérer l'auteur, on se retrouve devant un probleme, si personne ne s'est inscrit entre temps, il n'y a pas d'enregistrement 3 , la c'est OK mais si quelqu'un s'inscrit entretemps, on se retrouve avec qqn dont l'ID est 3 et qui n'EST PAS l'auteur des messages.

Donc pour utiliser ta méthode sans avoir de problemes, il faudrait ré-attribuer tout les champs de la table forum a un auteur 0 si il est supprimé, mais voila le probleme, cela demande plus de traitement et de vérifications par code que cela n'économise de place dans la base ou de performance.

En lui même le code est intéréssant pour son fonctionnement. Mais je pense qu'il ne doit pas etre utilisé pour une application concrete de base de données sinon on se retrouve devant plusieurs dilemes surtout en cas de base de données relationnelles (tres courantes)

Bonne prog

signaler à un administrateur
Commentaire de Kirua le 20/10/2004 16:29:20

bien vu Magidev, je te suis totalement sur ce point.

je rajouterai que si l'id a une signification par rapport aux données (par exemple, tu fais un script de votes pour une série de concours que tu organises, tu mets alors comme id le numéro du concours: il y a un sens direct), tu n'auras pas le problème de savoir s'ils se suivent ou pas: ça n'a plus de sens. Si par contre ton id n'est pas en relation directe avec les données: c'est uniquement un nombre qui permet d'identifier (justement) ces données précises, avec peu de mémoire, alors le fait que la série d'ID soit discontinue n'est pas un problème non plus: ce n'est pas une partie significative des données, on n'affiche jamais l'id, sauf dans les liens etc...

Donc on a bien que dans les deux cas qui peuvent se présenter, avoir une discontinuité dans les id ne pose pas de problème (même si on est bien d'accord que c'est moche :p)

signaler à un administrateur
Commentaire de pepito le 20/10/2004 19:57:18

Il n'en demeure pas moins que, dans certains cas précis, il peut être intéressant d'employer cette fonction (une certaine idée de l'esthétique des séquences) et qu'elle valait la peine d'etre postée.

signaler à un administrateur
Commentaire de Kirua le 20/10/2004 20:59:46

Note bien que je ne discute pas le fait que ça ait été posté. Même en programmation, la "recherche" pure et gratuite a son intérêt, fut-il seulement pédagogique. Je donne simplement un argument qui va dans le sens de la remarque de Magidev: ok, le code est intéressant, mais ne l'utilisez pas à moins que ça ne se justifie (auquel cas poster ici svp ^^ je serais étonné de trouver une situation où ça s'applique pertinament).

D'ailleurs, je n'ai pas noté le code.

signaler à un administrateur
Commentaire de ehmarc le 21/10/2004 09:58:15

Salut
Bin moi j'en ai besoin :p enfin un peu modifier (bon l'architecture de ma base est pas tres jolie mais elle m'est imposé donc...)
Dans mon cas, les index me servent juste pour une sélection plus simple apres l'affichage (je renvoie le numéro d'index à la page suivante... avec mon lien) sinon j'ai entendu parler de moulinette qui ferai ce genre de truc proprement (voir le cas du phorum plus haut) mais ceux que j'ai trouver sont payant....

signaler à un administrateur
Commentaire de kofu le 21/10/2004 12:13:05

Bonjour,

Il est clair que ce code est inutile pour les applications les plus courantes, mais je me suis dis que dans certains cas bien précis, elle pourrait l'être.

Toujours dans les recherches sur l'utilisation des clés primaires, j'ai créé un portail qui gère rubriques, articles etc.
L'ordre d'apparition est géré par les clés primaires (en termeinant la requête par un ORDER BY code ASC.
Pour modifier l'ordre d'apparition, il suffit d'échanger deux clés primaires.
Ca évite d'utiliser un champ "ordre", et les clés primaires ne sont pas dénaturées: Elles gardent leur fonction d'identifiant unique
Je ne pense pas que ce concept soit "nul", ou "excellent", mais juste "différent" ;)

Actuellement je suis sur un éditeur HTML WYSIWYG compatible avec mozilla, IE et opera, si quelqu'un est interessé pour me donner un coup de main, n'hésitez pas à me contacter à l'adresse se trouvant dans mon profil
@ bientôt pour d'autres sources bizzaroïdes

signaler à un administrateur
Commentaire de kofu le 21/10/2004 12:35:44

je rajouterai, pour compléter les dires de Magidev, que dans le cas d'une base de données relationelle (SGBDR), il est utile d'utiliser la mise à jour en cascade. Si un champ d'une table Y pointe sur la clé primaire d'une table X (notions de clés étrangères), et si on change la clé primaire d'un tuple de X, alors le champ de la table Y sera modifié aussi.
Ainsi, pas de perte de données.
En ce qui concerne la destruction d'un utilisateur de forum, on peut attribuer ses messages à l'utilisateur fictif "un membre déserteur" par exemple.
Bref, tout ça pour dire et répèter que cette fonction n'est pas forcement LA solution à utiliser, mais qu'elle peut être pratique et dépanner certaines personnes.

signaler à un administrateur
Commentaire de Anthomicro le 22/10/2004 22:57:32

Salut :-)

Le problème de ce code est qu'il est très gourmand pour une table comportant des milliers d'enregistrements...

mais l'idée est intéressante.

a ++

signaler à un administrateur
Commentaire de supergyver le 25/10/2004 01:04:39

Si deux internautes utilisent cette fonction pour ajouter un nouvel enregistrement il peut y avoir concurrence.
En effet, 'A' utilise la fonction qui lui renvoie 3.
'B' utilise la même fonction qui lui renvoie 3 aussi...
'A' fait son insertion, là c'est OK.
'B' fait son insertion et là... boom!!! insertion impossible

signaler à un administrateur
Commentaire de Kirua le 25/10/2004 07:52:13

tu veux dire s'ils le font en même temps? c'est le cas aussi en temps normal, avec auto increment, mais que je sache il n'y a jms de problème. mysql gère ce genre de situations. je ne sais pas comment, mais c'est géré ^^

signaler à un administrateur
Commentaire de kofu le 25/10/2004 10:24:14

C'est vrai que ce code n'est pas recommandé pour être utilisé en concurrence.
Il faut utiliser les transactions, en la dbutant avant getCode et en la terminant par un commit après l'insertion.

Au sujet de mysql et de sa gestion des concurrence, elle "ferait" du transactionnel au niveau TABLE, mais pas au niveau BdD ... Bref, elle gère la concurrence sur deux accès simultanés à la même table mais pas deux accès simultanés sur la même base de données

Corrigez moi si je me trompe

signaler à un administrateur
Commentaire de Kirua le 25/10/2004 17:02:50

mais à moins que tu ne permettes aux utilisateurs de modifier les structures des bases, je vois pas qd tu pourrais avoir besoin de plus que de la sécurité au niveau des tables, ce qui est tt de même bcp plus fréquemment indispensable.

signaler à un administrateur
Commentaire de supergyver le 26/10/2004 01:21:55

Mysql gère le problème de concurrence avec l'autoincrémente mais pas avec la méthode "manuelle...

------------------------
Si deux internautes utilisent cette fonction pour ajouter un nouvel enregistrement il peut y avoir concurrence.
En effet, 'A' utilise la fonction qui lui renvoie 3.
'B' utilise la même fonction qui lui renvoie 3 aussi...
'A' fait son insertion, là c'est OK.
'B' fait son insertion et là... boom!!! insertion impossible
------------------------
tu veux dire s'ils le font en même temps? c'est le cas aussi en temps normal, avec auto increment, mais que je sache il n'y a jms de problème. mysql gère ce genre de situations. je ne sais pas comment, mais c'est géré ^^
------------------------

signaler à un administrateur
Commentaire de kofu le 26/10/2004 19:08:34

La gestion des concurrences sur l'autoincrément n'est pas un fonctionnement standard SQL.

pour plus d'infos quant à l'utilisation des auto incréments, je vous conseille de vous référer à cet article:

http://sqlpro.developpez.com/cours/clefs/

A priori, l'utilisation d'une "table de clés" serait la solution la plus sûre, et la plus portable.
C'est d'ailleurs celle ci que j'utilise actuellement, getCode étant mon ancien système, je n'utilisais pas la concurrence.


N'hésitez pas à donner votre avis.

Ajouter un commentaire



Nos sponsors

Sondage...

CalendriCode

Juillet 2009
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
2728293031  

Consulter la suite du CalendriCode

Comparez les prix Nouvelle version


LG KP501

Entre 9€ et 159€


Photothèque Nouveau !



Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés
Temps d'éxécution de la page : 0,359 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.