Quelle est la bonne façon d'ajouter une CLÉ PRIMAIRE à une grande table InnoDB?

8

J'ai une table avec environ 30 millions de lignes dans MySQL 5.5 en utilisant le moteur de stockage InnoDB. Cette table a une clé étrangère qui relie à une autre table avec environ 3 millions de lignes.

Je veux ajouter une clé primaire à la plus grande table, mais je ne suis pas sûr de la meilleure façon de procéder. Il n'y a aucune colonne (ou ensemble de colonnes) existante que je peux utiliser pour cela, alors comment dois-je procéder?

J'ai vu quelques références à un ID d'enregistrement InnoDB interne, mais je n'ai pas trouvé s'il était accessible.

Sinon, je devrai peut-être vider et recharger les données, en ajoutant l'identifiant manuellement.

Merci.

Wodin
la source
Leur combinaison de touches dans la table est-elle naturellement unique? Si c'est le cas, une clé primaire à plusieurs colonnes pourrait avoir un sens.
Justin Dearing
Malheureusement, une telle clé composite n'était pas possible. Sinon, je conviens que cela aurait du sens. J'ai édité le message pour clarifier que cela n'était pas possible.
Wodin

Réponses:

7

ce n'est peut-être pas la bonne façon de procéder, mais ..

ne pourriez-vous pas simplement modifier la structure de la table,

ajouter une colonne de clé primaire à la table

puis...

écrire un script rapide pour parcourir toute la table

ajouter une valeur d'auto-incrémentation à la nouvelle colonne?

Patrick
la source
2
Merci pour la suggestion. Je pense que je devrais ajouter la colonne en tant que clé non primaire, puis la convertir en clé primaire par la suite, mais j'ai en fait découvert accidentellement lors d'un test sur une petite table, que l'ajout d'une colonne AUTO_INCREMENT (en tant que clé primaire) remplit automatiquement les identifiants. Je supposais que cela me donnerait une erreur, donc je pense que c'est la réponse.
Wodin
si la base de données est très utilisée, vous voudrez peut-être tester cela sur une table non critique pour vous assurer qu'elle ne la verrouille pas pendant longtemps
Patrick
@Patrick, merci pour la note de prudence. La base de données n'est pas actuellement utilisée et je m'attends à ce que cela verrouille la table pendant longtemps.
Wodin
1
Je l'ai fait ALTER TABLE blah ADD id INT NOT NULL AUTO_INCREMENT PRIMARY KEY;et cela a pris 2 heures et 18 minutes :) Je n'ai pas essayé d'écrire sur la table pendant ce temps, mais les lectures ont bien fonctionné.
Wodin
1
@Wodin wow, c'est long pour une commande alter table. heureux que cela ait fonctionné pour vous.
Patrick
3

Voici comment j'aborderais cela:

  1. Créez une nouvelle table avec la structure souhaitée, y compris votre CLÉ PRIMAIRE avec AUTO_INCREMENT et probablement un autre champ indexé.
  2. Prenez un temps d'arrêt pour arrêter tout trafic.
  3. Confirmez que vous disposez d'une sauvegarde légitime de vos données.
  4. Copiez toutes vos lignes de votre table existante dans la table cible en utilisant l'AUGMENTATION AUTOMATIQUE pour créer vos identifiants. * par exemple INSERT INTO target_table (col1, col2, etc) SELECT (col1, col2, etc) FROM origin_table; *
  5. Testez que les données de la nouvelle table sont exactes.
  6. RENOMMER l'ancienne table en origin_table_BAK.
  7. RENAMEz target_table en origin_table.
  8. Testez la fumée de votre application.
  9. Ouvrez-vous à la circulation.
  10. Après votre prochaine sauvegarde, supprimez origin_table_BAK.

* Remarque: Si la table d'origine est InnoDB, les contraintes de clé étrangère seront conservées et survivront au changement de nom. Vous devrez donc faire un changement pour y remédier.

randomx
la source
3
Si vous devez le faire en direct, suivez les étapes 6 et 7 en un seul RENAME, ce qui le rend atomique. RENAME TABLE real_name TO ancien, nouveau TO real_name;
Rick James