Qual é uma boa maneira de adicionar uma PRIMARY KEY a uma tabela grande do InnoDB?

8

Eu tenho uma tabela com cerca de 30 milhões de linhas no MySQL 5.5 usando o mecanismo de armazenamento InnoDB. Esta tabela possui uma chave estrangeira que se vincula a outra tabela com cerca de 3 milhões de linhas.

Quero adicionar uma chave primária à tabela maior, mas não tenho certeza da melhor maneira de fazer isso. Não há coluna (ou conjunto de colunas) existente que eu possa usar para isso; então, como devo proceder?

Eu vi algumas referências a um ID de registro interno do InnoDB, mas não encontrei se ele estiver acessível.

Caso contrário, talvez eu precise despejar e recarregar os dados, adicionando o ID manualmente.

Obrigado.

Wodin
fonte
É uma combinação de chaves na tabela que é naturalmente única? Nesse caso, uma chave primária de várias colunas pode fazer sentido.
Justin Dearing
Infelizmente, não havia essa chave composta possível. Caso contrário, eu concordo que faria sentido. Eu editei a postagem para esclarecer que isso não era possível.
Wodin

Respostas:

7

esse pode ser o caminho errado, mas ..

você não pode simplesmente alterar a estrutura da tabela,

adicione uma coluna de chave primária à tabela

então...

escreva um script rápido para percorrer a tabela inteira

adicionando um valor de incremento automático à nova coluna?

Patrick
fonte
2
Obrigado pela sugestão. Eu acho que teria que adicionar a coluna como uma chave não primária e depois convertê-la em chave primária posteriormente, mas na verdade descobri acidentalmente enquanto testava em uma pequena tabela que adicionava uma coluna AUTO_INCREMENT (como chave primária) preenche automaticamente os IDs. Estava assumindo que isso me daria um erro, então acho que é a resposta.
Wodin 01/02
se o banco de dados é alta utilização, você pode querer testar isso em uma tabela que não é crítica para se certificar de que não trancá-lo por um longo tempo
Patrick
@ Patrick, obrigado pela nota de cautela. O banco de dados não está em uso no momento e espero que isso bloqueie a tabela por um longo tempo.
Wodin 01/02
11
Eu fiz ALTER TABLE blah ADD id INT NOT NULL AUTO_INCREMENT PRIMARY KEY;e levou 2 horas e 18 minutos :) Eu não tentei escrever para a mesa durante esse tempo, mas as leituras funcionaram bem.
Wodin 02/02
11
@ Wodin uau, isso é muito tempo para um comando alter table. feliz que funcionou para você.
214 Patrick Patrick
3

Aqui está como eu abordaria isso:

  1. Crie uma nova tabela com a estrutura desejada, incluindo sua PRIMARY KEY com AUTO_INCREMENT e provavelmente um outro campo indexado.
  2. Tire um tempo de inatividade para parar todo o tráfego.
  3. Confirme se você tem um backup legítimo dos seus dados.
  4. Copie todas as suas linhas da tabela existente para a tabela de destino, aproveitando o INCREMENTO AUTOMÁTICO para criar seus IDs. * eg INSERT INTO target_table (col1, col2, etc) SELECT (col1, col2, etc) FROM tabela de origem; *
  5. Teste se os dados na nova tabela estão corretos.
  6. RENAME a tabela antiga para origin_table_BAK.
  7. RENAME tabela de destino para tabela de origem.
  8. Fumo teste sua aplicação.
  9. Aberto de volta ao tráfego.
  10. Após seu próximo backup, descarte origin_table_BAK.

* Nota: Se a tabela de origem for InnoDB, as restrições de chave estrangeira serão mantidas e sobreviverão à renomeação. Então você terá que fazer uma alteração para remediar isso.

randomx
fonte
3
Se você precisar fazê-lo ao vivo, execute as etapas 6 e 7 em um único RENAME, tornando-o atômico. RENAME TABLE real_name TO antigo, novo TO real_name;
Rick James