J'utilise InnoDB pour un projet et comptez sur Auto_Increment. Ce n'est pas un problème pour la plupart des tables, mais pour les tables avec suppression, cela pourrait être un problème: p>
Auto_Increment Manipulation à Innodb p>
en particulier cette partie: p>
Colonne Auto_Increment Nommé AI_COL: Après le démarrage du serveur, pour le premier insert dans une table T, Innodb exécute l'équivalent de cette déclaration: Sélectionnez max (AI_COL) de T pour la mise à jour; InnoDB incrémente par l'une de la valeur extraite par la déclaration et l'attribue à la colonne et au compteur d'incrément automatique pour la table. Blockquote>Ceci est un problème car pendant qu'il garantit que dans la table, la clé est unique, il y a des clés étrangères de cette table où ces clés ne sont plus uniques. P>
Le serveur MySQL fait / ne doit pas redémarrer souvent, mais cela se brise. Y a-t-il des façons simples autour de cela? P>
5 Réponses :
Utilisez une contrainte de clé étrangère avec "SET NULL" pour les mises à jour et les suppresses. P>
C'est le problème. J'ai copié et collé la mauvaise chose, en fait.
Y a-t-il un problème? La valeur maximale est rapidement dérivée de votre Index I>. Il n'y a pas d'analyse de table impliquée.
J'ai ajouté un peu plus d'explications en haut, mais le problème est qu'il existe d'autres tables faisant référence à cette table, à l'aide de l'ID comme reçu. Pour ces tables, cette colonne n'est plus unique.
Je pense que vous êtes mal compris la documentation. Lorsque vous insérez une ligne, l'ID généré automatiquement est enregistré sur le disque. La seule chose qui n'est pas enregistrée sur le disque est la cache de la valeur suivante, mais cela n'affecte pas la fonctionnalité. Cela donne simplement une très i> performance mineure sur le démarrage.
Le problème de l'OP est celui-ci: Insérez une ligne avec ID = 42 dans un tablier. Insérez une autre ligne avec une clé étrangère (42) dans la tableb. Supprimer ID = 42 du tablier. Redémarrez maintenant le serveur et insérez une autre ligne de tablea. Il obtiendra ID = 42 et la clé étrangère de référencement dans la tableb signifierait désormais les données qui ne sont vraiment pas liées
@NOS: OK, ça a du sens. Je ne pouvais pas résoudre ce que le problème ressort de la description de la question, mais je le vois maintenant. Les solutions sont simples cependant: InnoDB prend en charge les contraintes de clé étrangère. Ainsi, lorsque vous supprimez la ligne, vous pouvez vous assurer qu'aucune autre ligne ne pointe toujours là. J'ai mis à jour ma réponse.
Vous avez donc deux tables: p>
Tablea h2>
a_id [pk] p> blockQuote>
et p>
TABLEB H2>
b_id [pk] p>
a_id [fk, tablef.a_id] p> blockQuote>
et dans la tableb, la valeur d'A_ID n'est pas unique? Ou y a-t-il une valeur dans tableb.a_id qui n'est pas dans Tablea.a_id? P>
Si vous avez besoin de la valeur de tableb.a_id pour être unique, vous devez ajouter une contrainte unique à cette colonne. P>
ou est-ce que je manque toujours quelque chose? p>
Il y a une contrainte unique, ce qui est de savoir comment cela me manque - il essaie d'insérer dans la tableB A_ID qui existe déjà, en raison du redémarrage du serveur et de la réinitialisation automatique de la réinitialisation.
Si vous avez une contrainte de clé étrangère, comment pouvez-vous supprimer une rangée de la table A lorsque le tableau B références de cette ligne? Cela ressemble à une erreur pour moi.
Peu importe, vous pouvez éviter la réutilisation des valeurs d'incrémentation automatique en réinitialisant le décalage lorsque votre application recommence. Requête pour le maximum dans toutes les tables qui référent le tableau A, puis modifier le tableau ci-dessus sur ce maximum, par exemple. Si le MAX est 989, utilisez ceci: p>
alter table TableA auto_increment=999;
Semble juste. Je l'utilise un peu comme un reçu, bien que je devrais peut-être prendre une autre approche.
Créer une autre table avec une colonne qui se souvient de la dernière carte d'identité créée. De cette façon, vous n'avez pas à prendre en charge les valeurs maximales dans de nouvelles tables qui ont ceci comme clé étrangère. P>
j'ai vérifié.
http: // docs. oracle.com/cd/e17952_01/Refman-5.1-fr/innodb-auto-Increment-handling.html
InnoDB utilise l'algorithme suivant pour initialiser le compteur d'incrément automatique pour une table T contenant une colonne Auto_inCremmentation nommée AI_COL: et
http://docs.oracle.com/cd/e17952_01 /refman-5.1-fr/alter-Table.html P>
Vous ne pouvez pas réinitialiser le compteur à une valeur inférieure ou égale à celle qui a déjà été utilisée. strong> p>
C'est la raison pour laquelle Alter Table ne fonctionnera pas. Je pense que seule l'option est d'essuyer les données et de la réécrire dans une nouvelle table avec un nouvel identifiant.
Dans ma table de cas était logfile, alors je faisais juste: p>
Rename Table SystemEvents à SystemEvents_old;
Créer une table SystemEvents comme SystemEvents_old; P>
Corrigé dans mysql 8.0: dev.mysql.com/worklog/task/?id=6204