Modifier les ID auto increment dynamiquement

Eléphant du PHP | 76 Messages

14 oct. 2012, 05:50

Bonjour tout le monde,

J'aurais une petite question.

Est-ce possible de modifier dynamiquement les id auto_increment d'une table mysql?

Je m'explique :

J'ajoute un produit dans ma base de donnée depuis un formulaire sur le site web.

L'id devient, exemple "5".

Je supprime ce produit, depuis une autre page du site.

Ensuite, j'ajoute un nouveau produit et le id de celui-ci est "6".

Est-ce possible qu'il soit nommé "5"? Merci

Mammouth du PHP | 2278 Messages

14 oct. 2012, 09:08

puisqu'il est auto-increment c'est non par définition, à tel point que la doc officielle conseille d'employer un type de nombre assez grand pour pouvoir loger tous les enregistrements prévisibles; au-dela, mysql génèrerait une erreur lors d'une insertion. Et puis, à l'emploi, ce serait assez malcommode : il faudrait tenir à jour une table des suppressions et la consulter avant de faire une insertion.
On pourrait imaginer que mysql fasse du ménage périodiquement dans ce type de champ ou dispose d'une commande le faisant
En cas de débordement, on peut toujours copier la table pleine dans une nouvelle table, etc
Vanitas vanitatum et omnia vanitas
Mes derniers livres :
Sauvez les Mots chez BoD,
Tous les chemins mènent à ROM chez BoD

ViPHP
xTG
ViPHP | 7331 Messages

14 oct. 2012, 09:27

D'autant plus que tu vas faire quoi en cas de suppression de l'enregistrement 5 sur 10 000 ? Décaler les 9 994 IDs ? ^^
Si c'est par un souci d'optimisation voir les propos de sirakawa, si c'est pour un souci d'id manquant utilises une autre colonne mais personnellement je vois pas tellement pourquoi s'embêter pour si peu.

Mammouth du PHP | 2278 Messages

14 oct. 2012, 17:00

Non xtg,
Si je DEVAIS faire une chose comme ça, j'aurais une table normale, avec les id simplement entiers et uniques, et une table

identificateurs
avec un champ nb_id_liberes, un champ id_max
une table liberes
libre entier
Quand je fais une insertion, je consulte la table identificateurs. Si nb_liberes != 0, je consulte liberes pour prendre le premier id que je trouve, je le supprime de liberes, je met à jour identificateurs en décrémentant nb_libres et, ouf, je mets à jour la table principale. Si nb_liberes == 0, je mémorise id_max j'incremente dans la table identificateurs etc
Similaire en cas de suppressionen remplacant suppression par insertion et décrément par incrément.

Mais, il faut biien admettre que c'est beaucoup de sport pour pas grand chose. Autant écrire son propre SGBD...
Vanitas vanitatum et omnia vanitas
Mes derniers livres :
Sauvez les Mots chez BoD,
Tous les chemins mènent à ROM chez BoD

ViPHP
xTG
ViPHP | 7331 Messages

14 oct. 2012, 17:42

Je suis pleinement d'accord avec toi.
Je n'ai pas approndi ma pensée car cela ne me semble de manière pas une bonne idée.

Eléphant du PHP | 76 Messages

14 oct. 2012, 20:49

Merci pour vos explications.

En fait, j'avais simplement pensé afficher exemple, les ID 1 à 10 de tel tables.. Mais j'imagine qu'on peux seulement afficher les 10 premiers résultats retourné haha.

Donc, vous conseillez de placer un gros nombre à la valeur de INT?

Merci encore.

Mammouth du PHP | 2278 Messages

14 oct. 2012, 21:03

ca c'est l' attribut limit de mysql
Vanitas vanitatum et omnia vanitas
Mes derniers livres :
Sauvez les Mots chez BoD,
Tous les chemins mènent à ROM chez BoD

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

15 oct. 2012, 12:32

Donc, vous conseillez de placer un gros nombre à la valeur de INT?
déjà tu peux utiliser le unsigned de mysql pour n’avoir qu'un entier positif (tu double donc le nombre max pour un int).
si tu crois que tu va avoir énormément d'enregistrement (ou si tu es parano tu peux utiliser un bigint unsigned :mrgreen: ).

attention unsigned c'est seulement mysql (par exemple avec oracle tu utiliserais un number(38,0) valeur max : 10 exp 127 ;) )



@+
Il en faut peu pour être heureux ......

Eléphant du PHP | 76 Messages

15 oct. 2012, 14:32

Oui, un peu parano, merci :)

Mammouth du PHP | 2278 Messages

15 oct. 2012, 19:12

Je viens d'avoir une idée d'une si profonde débilité que je vous la livre; ne sortez pas les plumes et le goudron, par pitié!
on ajoute une colonne : activite tinyint ça suffit
un article créé et validé : valeur 1
créé mais pas validé : valeur 2
supprimé valeur 3
ça complique un peu les consultations, menfin.
Quand, et seulement quand, la table refuse d'enregistrer parce qu'elle est pleine, ou quand elle atteint un seuil qu'on s'est fixé, on se sert s'il en existe un, d'un article marqué 3. C'est un indice qu'il faut faire de la maintance, voire du transfert.


Ou le loup, la chèvre et le chou sont dans un bateau. Le loup dit à Toto : Es-tu végétarien?" Toto répond "Non pourquoi ?- Parce que moi non plus et il ne reste qu'un chou et la chèvre qui a mangé les autres choux."
Question :
D'où sort Toto?
Vanitas vanitatum et omnia vanitas
Mes derniers livres :
Sauvez les Mots chez BoD,
Tous les chemins mènent à ROM chez BoD

ViPHP
xTG
ViPHP | 7331 Messages

15 oct. 2012, 20:04

Il est plus simple de supprimer les enregistrements puis de récupérer tous les IDs non utilisés via une simple requête. :)

Mammouth du PHP | 2278 Messages

15 oct. 2012, 20:06

Il est plus simple de supprimer les enregistrements puis de récupérer tous les IDs non utilisés via une simple requête. :)
bien sûr que non, si les id sont autoincrement. On ne peut pas les récupérer, à ma connaissance du moins.
Vanitas vanitatum et omnia vanitas
Mes derniers livres :
Sauvez les Mots chez BoD,
Tous les chemins mènent à ROM chez BoD

ViPHP
ViPHP | 2577 Messages

15 oct. 2012, 20:38

On ne peut pas faire un insert en fixant la valeur de l'index ?
Il me semble que l'auto incrément fonctionne en tant que valeur par défaut.
Il est également possible de fixer la valeur de départ de l'auto incrément.

Autrement, j'avais entendu dire qu'un timestamp pouvait être utilisé comme clé unique (qu'il était impossible de faire 2 inserts avec le même timestamp)

Mammouth du PHP | 2278 Messages

15 oct. 2012, 22:10

Chalut,
C'est un sujet qui m'avait déjà turlupiné quand je mettais au point une bidulerie gérant des élèves : tous les ans, dans un lycée de 1500, il en disparait environ 500, soit qu'ils aient le bac, soit qu'ils soient allés gagner leur culture ailleurs, et il en arrive environ 500. Enj fait, je suppose que d'énormes id ne gênent pas lorsqu'on fait des jointures, mais entre ce que je crois et ce qui est, il y a le monde de la doc officielle mysql, d'une transparence voisine parfois de l'opacité (Je sais bien qu'un SGBD est une boîte noire...)

à ma connaissance et à la lecture de la doc officielle, on peut fixer au départ la valeur de début et après il faut laisser faire mysql. si non ça donne ça que je viens de tester
une base où il y avait 5 enregistrements id auto de 1 à 5
je balance un
insert ... set id = 341;
ok, ça fonctionne
à partir de maintenant (sans rien dire sur l'id) :
insert into ... set nom ='titi';
lui met l'id 342...
et avec insert ... set id = 0; ou set id= NULL;
même combat, même résultat.
Vanitas vanitatum et omnia vanitas
Mes derniers livres :
Sauvez les Mots chez BoD,
Tous les chemins mènent à ROM chez BoD

ViPHP
AB
ViPHP | 5818 Messages

16 oct. 2012, 00:23

puisqu'il est auto-increment c'est non par définition
Si c'est possible, cf message de Mazarini
et avec insert ... set id = 0; ou set id= NULL;
même combat, même résultat.
Cet exemple n'est pas signifiant dans le sens où comme ces valeurs ne sont pas des id valides et correspondent (pour un id) à null, c'est la valeur par défaut qui est insérée et donc l'auto incrément fonctionne normalement...

Mazarini a raison, tu peux très bien fixer l'auto incrément toi-même à des valeurs inférieures à la valeur maximale en cours, tant que l'id n'est pas déjà utilisé (même s'il a été utilisé puis effacé). On peut donc considérer l'auto incrément simplement comme une fonction qui donne une valeur par défaut.

Pour répondre à rickphp, on pourrait donc éviter les trous dans les id en recherchant la plus petite valeur non utilisée (qui a été supprimée) mais ce serait fastidieux et c'est bien s'embêter pour rien car le temps que tu dépasse la valeur maximale avec un "int", ton application sera aux oubliettes depuis longtemps.

Sinon pour info ce comportement n'est pas identique pour toutes les tables :
Si vous effacez des lignes contenant la valeur maximum d'une colonne AUTO_INCREMENT, la valeur sera réutilisée pour une table ISAM ou BDB, mais pas pour une table MyISAM ou InnoDB.
source

Le plus simple est donc de suivre les conseils de moogli : "int" avec le "unsigned" puisque de toutes façons on utilise pas les valeurs négatives, mais ne mets un "bigint" que vraiment si nécessaire sinon cela prend inutilement de la place dans ta table (de même que si tu utilise un champ longtext alors qu'un champ texte suffirait). Tu pourras toujours changer pour un "bigint" si le besoin s'en fait sentir un jour.