Se passer de l'auto incrément

Soyez le premier à donner votre avis sur cette source.

Snippet vu 4 142 fois - Téléchargée 32 fois


Contenu du snippet

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

Source / Exemple :


/***************************************

    • 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)

A voir également

Ajouter un commentaire

Commentaires

kofu
Messages postés
25
Date d'inscription
vendredi 2 janvier 2004
Statut
Membre
Dernière intervention
15 mars 2005

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.
supergyver
Messages postés
29
Date d'inscription
jeudi 19 février 2004
Statut
Membre
Dernière intervention
14 février 2007

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é ^^
------------------------
cs_Kirua
Messages postés
3006
Date d'inscription
dimanche 14 avril 2002
Statut
Membre
Dernière intervention
31 décembre 2008

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.
kofu
Messages postés
25
Date d'inscription
vendredi 2 janvier 2004
Statut
Membre
Dernière intervention
15 mars 2005

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
cs_Kirua
Messages postés
3006
Date d'inscription
dimanche 14 avril 2002
Statut
Membre
Dernière intervention
31 décembre 2008

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é ^^

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.