Suponha que eu tenha uma tabela de banco de dados com um arquivo ENUM('value_one','value_two')
. Eu quero mudar isso para um arquivo ENUM('First value','Second value')
. Atualmente estou fazendo isso da seguinte forma:
ALTER TABLE `table` MODIFY `column` ENUM('value_one','value_two','First value','Second value');
UPDATE `table` SET `column`='First Value' WHERE `column`='value_one';
UPDATE `table` SET `column`='Second Value' WHERE `column`='value_two';
ALTER TABLE `table` MODIFY `column` ENUM('First value','Second value');
Existe uma maneira mais eficiente de fazer isso, por exemplo, uma maneira de fazer isso com uma única ALTER TABLE
instrução?
A técnica a seguir que estou prestes a mostrar exigirá coragem de aço.
Dados os seguintes critérios
/var/lib/mysql
mydb.mytb
enum_col
Aqui está uma rachadura que desafia a morte:
CREATE TABLE mydb.mybt LIKE mydb.mytb;
ALTER TABLE mydb.mybt MODIFY enum_col ENUM('First value','Second value');
SET wait_timeout=86400; SET interactive_timeout=86400;
FLUSH TABLES WITH READ LOCK;
Em uma sessão OS/SSH separada, troque os arquivos .frm
$ mv /var/lib/mysql/mydb/mytb.frm /var/lib/mysql/mydb/myxx.frm
$ mv /var/lib/mysql/mydb/mybt.frm /var/lib/mysql/mydb/mytb.frm
$ mv /var/lib/mysql/mydb/myxx.frm /var/lib/mysql/mydb/mybt.frm
UNLOCK TABLES;
DROP TABLE mydb.mybt;
É isso !!!
AVISO: NÃO POSSO TOMAR CRÉDITO POR ISSO!
Esta técnica vem de "MySQL de alto desempenho: otimização, backups, replicação e mais", páginas 146-148 sob o subtítulo Acelerando ALTER TABLE . Página 147 O parágrafo 1 diz:
De uma chance ! (Por favor, deixe-nos saber como ficou)
ATUALIZAÇÃO 2011-10-05 17:49 EDT
Se a tabela for MyISAM e você tiver espaço suficiente na produção e uma janela de tempo de inatividade direta, tente o seguinte:
service mysql restart --skip-networking
Em uma sessão OS/SSH separada, faça uma cópia da tabela
cp /var/lib/mysql/mydb/mytb.frm /var/lib/mysql/mydb/mytbplay.frm
cp /var/lib/mysql/mydb/mytb.MYD /var/lib/mysql/mydb/mytbplay.MYD
cp /var/lib/mysql/mydb/mytb.MYI /var/lib/mysql/mydb/mytbplay.MYI
INFORMATION_SCHEMA.TABLES
detectará automaticamente a presença da nova tabela chamadamydb.mytbplay
.Execute o algoritmo de coragem de aço em
mydb.mytbplay
Você testa a integridade de
mydb.mytbplay
Se você está satisfeito
ALTER TABLE mydb.mytb RENAME mydb.mytb_backup;
ALTER TABLE mydb.mytbplay RENAME mydb.mytb;
service mysql restart
De uma chance!
Uma solução simples seria:
1- adicione uma nova coluna:
ALTER TABLE `table` ADD `enum2` ENUM('First value', 'Second value') NOT NULL AFTER `enum`;
2- Copie o valor da coluna para enum2 com substituições:
UPDATE `table` SET enum2=REPLACE(`column`, "value_one", "new value")
3- Solte a coluna
column
, renomeieenum
paracolumn
.NOTA : esta questão volta para 2011-10-05, minha solução é válida para MYSQL 4.1 e mais recente (AFAIK)