83 votes

Incrémentation automatique après suppression dans MySQL

J'ai une table MySQL avec un champ de clé primaire qui a AUTO_INCREMENT activé. Après avoir lu d'autres messages sur ce site, j'ai remarqué que d'autres personnes avaient le même problème, avec des réponses variées. Certains recommandent de ne pas utiliser cette fonctionnalité, d'autres affirment qu'elle ne peut pas être "réparée".

Je l'ai fait :

table: course
fields: courseID, courseName

Exemple : nombre d'enregistrements dans la table : 18. Si je supprime les enregistrements 16, 17 et 18, je m'attends à ce que le prochain enregistrement saisi ait l'ID de cours 16, mais il sera 19 car le dernier ID de cours saisi était 18.

Mes connaissances en SQL ne sont pas extraordinaires, mais existe-t-il un moyen de rafraîchir ou de mettre à jour ce compte avec une requête (ou un paramètre dans l'interface phpMyAdmin) ?

Cette table sera liée à d'autres dans une base de données.


Compte tenu de tous ces conseils, j'ai décidé d'ignorer ce "problème". Je vais simplement supprimer et ajouter des enregistrements tout en laissant l'incrémentation automatique faire son travail. Je suppose que le numéro n'a pas vraiment d'importance puisqu'il n'est utilisé que comme identifiant unique et qu'il n'a pas de (comme mentionné ci-dessus). entreprise sens.

Pour ceux que j'ai pu confondre avec mon message original : Je ne souhaite pas utiliser ce champ pour savoir combien d'enregistrements je possède. Je voulais simplement que la base de données ait un aspect soigné et un peu plus de cohérence.

3 votes

Que pensez-vous qu'il se passe si vous supprimez seulement l'enregistrement 16 ?

0 votes

Bon point ! J'aurais dû le mentionner. Idéalement, il faudrait tout décaler d'un

0 votes

Je me heurte à un problème qui est, d'une certaine manière, l'inverse du vôtre. En d'autres termes, j'ai un ENTITY table et un ENTITY_LOG table. Chaque fois que j'insère, mets à jour ou supprime quelque chose de la table ENTITY je consigne cette activité dans le ENTITY_LOG ainsi que le nom de l'entité Id . Récemment, un utilisateur a supprimé un tas d'entrées dans la base de données de la ENTITY et les entrées correspondantes ont été effectuées dans la table de journalisation. Aujourd'hui, lorsqu'un autre utilisateur a tenté d'ajouter une nouvelle entrée dans la table ENTITY le tableau généré Id se trouve être la même qu'une entité précédemment supprimée ! J'utilise JdbcTemplate et InnoDB.

81voto

Dolph Points 12741

Ce que tu essaies de faire semble dangereux, car ce n'est pas l'usage prévu de l'appareil. AUTO_INCREMENT .

Si vous voulez vraiment trouver la plus petite valeur de clé non utilisée, n'utilisez pas AUTO_INCREMENT du tout, et gérez vos clés manuellement. Toutefois, cette pratique n'est PAS recommandée.

Prenez du recul et demandez " pourquoi vous devez recycler les valeurs clés ? " Faire non signé INT (ou BIGINT ) ne fournit pas un espace clé suffisamment grand ?

Allez-vous vraiment avoir plus que 18,446,744,073,709,551,615 enregistrements uniques au cours de la durée de vie de votre application ?

1 votes

Vous avez raison. C'est mieux de l'ignorer. Étant donné que c'est seulement pour un devoir, je ne vais pas entrer dans des chiffres élevés et la durée de vie est très courte.

4 votes

Sont très dangereux pour un certain nombre de raisons. Premièrement, dans un système multi-utilisateurs, vous pouvez avoir des centaines, des milliers de mises à jour par seconde et essayer de réécrire l'auto inc pourrait soit ralentir le système, soit le compromettre. Deuxièmement, un autre développeur ne saurait pas que vous =faites cela et pourrait lier des enregistrements par l'intermédiaire de l'id, corrompant ainsi le système. etc.

0 votes

Les bons points. La réponse m'a fait réfléchir à deux fois. Pour ma part, je cherchais à ce qu'il n'y ait pas de vide dans l'auto_incr. parce que j'avais l'intention de boucler les identifiants. Mais je suppose que c'est mieux de simplement boucler sur les lignes :)

48voto

monksp Points 381
ALTER TABLE foo AUTO_INCREMENT=1

Si vous avez supprimé les entrées les plus récentes, cela devrait lui permettre d'utiliser la prochaine entrée disponible la plus basse. Ainsi, tant qu'il n'y a pas déjà 19, la suppression de 16-18 réinitialisera l'auto-incrément pour utiliser 16.


EDIT : J'ai raté le passage sur phpmyadmin. Vous pouvez le définir là aussi. Allez à l'écran de la table, et cliquez sur l'onglet des opérations. Il y a un AUTOINCREMENT que vous pouvez définir manuellement comme vous le souhaitez.

1 votes

Le PO peut le faire, mais il ne devrait pas. Vous devriez vraiment reconsidérer ce conseil étant donné ce que le PO essaie de faire.

12 votes

Ce n'est pas à moi de lui dire comment agencer sa base de données, ou comment faire sa logique commerciale. Il a également mentionné dans son message qu'il a lu d'autres messages/pages affirmant que c'est une mauvaise idée, donc il sait que ce n'est pas une pratique recommandée, mais il le fait quand même.

7 votes

C'est la réponse la plus directe actuellement fournie à la seule question explicite de l'auteur de la demande. Il n'y a pas de "conseil".

17voto

Darin Dimitrov Points 528142

Les clés primaires autoincrémentées dans les bases de données sont utilisées pour identifier de manière unique une ligne donnée et ne devraient pas recevoir de clé de type entreprise sens. Laissez donc la clé primaire telle quelle et ajoutez une autre colonne appelée par exemple courseOrder . Ensuite, lorsque vous supprimez un enregistrement de la base de données, vous pouvez vouloir envoyer une instruction UPDATE supplémentaire afin de décrémenter la valeur de l'enregistrement. courseOrder de toutes les lignes qui ont courseOrder supérieure à celle que vous êtes en train d'effacer.

À titre d'information, vous ne devriez jamais modifier la valeur d'une clé primaire dans une base de données relationnelle, car d'autres tables pourraient y faire référence en tant que clé étrangère et la modifier pourrait violer les contraintes référentielles.

0 votes

Il cherche à maintenir un compte, pas un ordre. L'UPDATE semble inutile.

0 votes

S'il cherche à maintenir un compte, il n'est pas nécessaire d'ajouter des colonnes supplémentaires. Le simple count La fonction agrégat fera l'affaire.

0 votes

Ok, merci. Beaucoup de réponses/commentaires en si peu de temps ! :O J'essaie de tout assimiler. Je vais regarder dans la fonction de comptage :)

4voto

Mike Sherov Points 6955

Vous ne devriez pas vous fier à l'identifiant AUTO_INCREMENT pour savoir combien d'enregistrements vous avez dans la table. Vous devriez utiliser SELECT COUNT(*) FROM course . Les ID sont là pour identifier de manière unique le cours et peuvent être utilisés comme références dans d'autres tables. Vous ne devriez donc pas répéter les ID et ne devriez pas chercher à réinitialiser le champ d'incrémentation automatique.

0 votes

Je crois qu'il pense que c'est une sorte d'insecte. MySQL a 20 ans. Ce n'est certainement pas un oubli. Il y a une très bonne raison pour laquelle l'auto incrémentation ne recycle pas les clés. Vous avez tout à fait raison, Mike.

1voto

Engr Arefin Points 48

J'ai une méthode très simple mais délicate.

Lors de la suppression d'une ligne, vous pouvez conserver les ID dans une autre table temporaire. Ensuite, lorsque vous insérerez de nouvelles données dans le tableau principal, vous pourrez rechercher et sélectionner les identifiants dans le tableau temporaire. Donc, utilisez une vérification ici. Si la table temporaire n'a pas d'identifiants, calculez l'identifiant maximal dans la table principale et définissez le nouvel identifiant comme suit : new_ID = old_max_ID+1 .

NB : Vous ne pouvez pas utiliser la fonction d'auto-incrémentation ici.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X