¿Cuál es una buena manera de agregar una CLAVE PRIMARIA a una tabla InnoDB grande?

8

Tengo una tabla con alrededor de 30 millones de filas en MySQL 5.5 usando el motor de almacenamiento InnoDB. Esta tabla tiene una clave externa que se vincula a otra tabla con alrededor de 3 millones de filas.

Quiero agregar una clave principal a la tabla más grande, pero no estoy seguro de cuál es la mejor manera de hacerlo. No hay una columna (o conjunto de columnas) existente que pueda usar para esto, entonces, ¿cómo debo hacer esto?

He visto algunas referencias a un ID de registro interno de InnoDB, pero no he encontrado si es accesible.

De lo contrario, tal vez deba volcar y volver a cargar los datos, agregando la identificación manualmente.

Gracias.

Wodin
fuente
¿Es una combinación de teclas en la tabla que es naturalmente única? Si es así, una clave primaria de varias columnas podría tener sentido.
Justin Dearing
Desafortunadamente, no había tal clave compuesta posible. De lo contrario, estoy de acuerdo en que tendría sentido. He editado la publicación para aclarar que esto no fue posible.
Wodin

Respuestas:

7

Esta puede ser la forma incorrecta de hacerlo, pero ...

¿No podrías simplemente alterar la estructura de la tabla?

agregar una columna de clave principal a la tabla

entonces...

escribir un guión rápido para revisar toda la tabla

¿Agregar un valor de incremento automático a la nueva columna?

Patricio
fuente
2
Gracias por la sugerencia. Creo que tendría que agregar la columna como clave no primaria y luego convertirla en clave primaria después, pero en realidad descubrí accidentalmente mientras probaba en una tabla pequeña, que agregar una columna AUTO_INCREMENT (como clave principal) rellena automáticamente los identificadores. Supuse que solo me daría un error, así que creo que esa es la respuesta.
Wodin
si la base de datos es de alto uso, es posible que desee probar esto en una tabla no crítica para asegurarse de que no se bloquee durante mucho tiempo
Patrick
@Patrick, gracias por la nota de precaución. La base de datos no está en uso actualmente y espero que esto bloquee la tabla durante mucho tiempo.
Wodin
1
Lo hice ALTER TABLE blah ADD id INT NOT NULL AUTO_INCREMENT PRIMARY KEY;y me tomó 2 horas y 18 minutos :) No intenté escribir en la mesa durante ese tiempo, pero las lecturas funcionaron bien.
Wodin
1
@Wodin wow, eso es mucho tiempo para un comando alter table. Me alegro que funcionó para usted.
Patrick
3

Así es como abordaría esto:

  1. Cree una nueva tabla con la estructura deseada, incluida su CLAVE PRIMARIA con AUTO_INCREMENTO y probablemente otro campo indexado.
  2. Tómese un tiempo de inactividad para detener todo el tráfico.
  3. Confirme que tiene una copia de seguridad legítima de sus datos.
  4. Copie todas sus filas de su tabla existente en la tabla de destino aprovechando el INCREMENTO AUTOMÁTICO para crear sus identificadores. * p. ej. INSERTAR EN tabla_destino (col1, col2, etc.) SELECCIONAR (col1, col2, etc.) DESDE tabla_origen; *
  5. Pruebe que los datos en la nueva tabla sean precisos.
  6. RENOMBRAR la tabla anterior a origin_table_BAK.
  7. RENAME target_table a origin_table.
  8. Prueba de humo en tu aplicación.
  9. Abierto de nuevo al tráfico.
  10. Después de su próxima copia de seguridad, suelte origin_table_BAK.

* Nota: Si la tabla de origen es InnoDB, las restricciones de clave externa se mantendrán y sobrevivirán al cambio de nombre. Entonces tendrá que hacer un cambio para remediar eso.

randomx
fuente
3
Si necesita hacerlo en vivo, siga los pasos 6 y 7 en un solo RENAME, para que sea atómico. RENAME TABLE real_name TO old, new TO real_name;
Rick James