J'ai récemment lu qu'en raison de la façon dont InnoDB recalcule la valeur AUTO_INCREMENT lorsque le serveur redémarre, tous les enregistrements situés dans la partie supérieure de la liste d'ID peuvent voir leurs ID réutilisés.
Normalement, ce n'est pas un problème, car lorsqu'un utilisateur est supprimé, tout ce qui est associé à l'ID est également supprimé des autres tables.
Mais je laisse délibérément leurs messages de forum orphelins, étiquetés "Posté par = Utilisateur # 123 =", afin que les conversations passées soient conservées. De toute évidence, si un ID est réutilisé, ce sera un problème.
Je n'ai jamais eu ce problème auparavant car il y avait toujours suffisamment de nouveaux utilisateurs pour qu'il soit peu probable qu'un ID soit réutilisé de cette manière. Cependant, sur mon nouveau projet, les inscriptions sont rares et les suppressions d'utilisateurs inactifs sont fréquentes (surtout depuis que les comptes "Open Alpha" ne durent que trois jours en tant qu'aperçu), et une telle réutilisation des ID s'est produite trois à trois maintenant.
J'ai "résolu" le problème en enregistrant la valeur correcte pour AUTO_INCREMENT ailleurs et en l'utilisant au lieu de compter sur la valeur interne. Existe-t-il un moyen réel pour qu'InnoDB se souvienne de la dernière valeur réelle?
Réponses:
(éviter le problème en ne supprimant jamais)
Étant donné que vous souhaitez conserver les
"Posted by =User #123="
informations après avoir supprimé l'utilisateur avecid=123
, vous pouvez également envisager d'utiliser 2 tableaux pour stocker les données des utilisateurs. Un pour lesActive
utilisateurs et un pour tous (y compris ceux supprimés des utilisateurs actifs). Et ne supprimez jamais ces identifiants duAllUser
tableau:Cela compliquera bien sûr l'opération d'insertion d'un nouvel utilisateur. Tout nouvel utilisateur signifiera 2 insertions, une dans chaque tableau. Cependant, la suppression d'un utilisateur se fera
ActiveUser
uniquement par suppression du tableau. Tous les FK seront supprimés en cascade, à l'exception des messages du forum, qui feront référence à laAlluser
table (où aucune suppression ne se produira jamais).la source
Il n'y a aucun moyen naturel de le faire, sauf d'utiliser information_schema.tables pour enregistrer toutes les colonnes avec l'option auto_increment.
Vous pouvez collecter ces colonnes comme suit:
Créez un script qui réinitialisera les valeurs auto_increment
Vous pouvez alors faire l'une des deux choses suivantes:
OPTION # 1: exécuter le script manuellement après le démarrage
OPTION # 2: Demandez à mysqld d'exécuter le script avant d'autoriser les connexions
Vous devez ajouter cette option
De cette façon, chaque fois que vous redémarrez mysql, ce script est exécuté au début. Vous devrez vous rappeler de régénérer /var/lib/mysql/ResetAutoInc.sql avant de faire un redémarrage prévu de mysql.
la source
La documentation 5.5 suggère de stocker la valeur d'incrémentation automatique ailleurs comme vous l'avez déjà fait.
Une solution alternative serait d'émuler une SEQUENCE afin de ne pas utiliser l'incrémentation automatique dans la table elle-même. Cela a été discuté sur le SO avant et à nouveau . Le blog MySQL Performance le mentionne.
Pourtant, une autre donnée MySQL vissée que les autres SGBDR n'ont pas ...
la source
Ne supprimez simplement pas l'utilisateur. L'intégrité relationnelle est plus importante. Si vous devez le faire pour des raisons de confidentialité ou autre, changez simplement le nom d'utilisateur en «supprimé» et effacez tous les autres champs.
la source
C'est une vieille question et toujours d'actualité.
1) Ce problème est en cours de correction dans Mysql 8.0.
2) Une solution consiste à utiliser une ligne fictive pour vos données, afin de maintenir l'AUTO_INCREMENT au-dessus d'une certaine valeur. Pas super pratique selon ce que vous stockez, mais c'est une solution simple dans certains cas.
la source
Nous avions besoin d'une solution extrapolée pour notre propre système basée sur les instructions de ce post. Si cela peut aider n'importe qui à atteindre son objectif de manière encore plus simple.
Notre système utilise un modèle de table tombstone pour stocker les éléments supprimés car nous effectuons une synchronisation bidirectionnelle sur les systèmes déconnectés, nous utilisons donc ce code pour faire correspondre les tables tombstone avec leurs tables en direct et extraire la valeur la plus élevée possible :)
la source