MySQL – Migrando uma base em LATIN1 para UTF8

Postado em: 5 de dezembro de 2013 - Por: Bruno Gunter

Este é um passo a passo para conversão de uma base de dados MySQL, já em produção, de Latin1 para UTF-8, que frequentemente passo para nossos clientes de hospedagem de WordPress e outros CMS.

A própria documentação do WordPress ensina como fazer esta conversão, mas o script não é 100% funcional. Como neste exemplo retirado do Codex no WordPress:

#!/bin/bash
USER=user
PASSWORD=password
DB=db

doAllTables() {
# get the table names
TABLENAMES=`mysql -u $USER -p$PASSWORD -D $DB -e "SHOW TABLES\G;"|grep 'Tables_in_'|sed -n 's/.*Tables_in_.*: \([_0-9A-Za-z]*\).*/\1/p'`
# loop through the tables and convert them
for TABLENAME in $TABLENAMES
do
mysql -u $USER -p$PASSWORD -D $DB -e "ALTER TABLE $TABLENAME CHARACTER SET utf8;"
done
}

doAllTables

Este exemplo tem uma margem de erro acima do aceitável. Então a recomendação que podemos fazer é criar uma nova database já em UTF-8 e converter o banco de forma adequada.

Então, vamos começar!

Passo 1: Criar uma nova Base de Dados

Você vai precisar ter permissões para criar um novo banco de dados em seu MySQL. Do Console MySQL, faça:

create database banco_novo character set utf8 collate utf8_general_ci;

Atenção: novo_banco é o nome desejado. Lembrando que no MySQL nenhum componente estrutural pode conter pontos “.”.

Passo 2: Criando os usuários MySQL

Do console MySQL, crie um usuário e dê as permissôes necessárias. Por exemplo:

create user 'usuario_novo'@'%' identified by 'SUA_SENHA';
grant all privileges on *.* to 'usuario_novo'@'localhost' with grant option;
flush privileges;

Passo 3: Backup do banco em produção

É fundamental guardarmos um backup do banco atual para eventualidades. Então guarde-o em um local seguro!

mysqldump --add-drop-table -h localhost -u usuario_producao -pSUA_SENHA_PRODUCAO banco_producao | bzip2 > backup_banco_producao.sql.bz2

Nota: Neste exemplo estamos comprimindo a saída do mysqldump enquanto on the fly. Assim poupamos espaço em disco.

Para importar este dump em caso de necessidade, use:

bunzip2 < backup_banco_producao.sql.bz2 | mysql -h localhost -u usuario_producao -pSUA_SENHA banco_producao

Passo 4: Convertendo os dados de Latin1 para UTF8

Para converter os dados, importando no novo banco é simples e pode ser executado em uma única linha no console local de seu servidor (Linux).

mysqldump --add-drop-table -h localhost -u usuario_producao -pSUA_SENHA_PRODUCAO banco_producao | sed 's/CHARSET=latin1/CHARSET=utf8/g' | iconv -f latin1 -t utf8 | mysql -h localhost -u usuario_novo -pSENHA_BANCO_NOVO banco_novo

Atenção! Se você possui um banco grande, recomendamos executar este passo em quatro etapas diferentes: primeiro o dump, segundo o sed, terceiro o iconv; e por fim a importação na nova base. Desta forma, minimizaremos a possibilidade de falhas.

nuvem_hibrida_reduz_custo_ti

Passo 5: Teste a conversão!

Como o collation utf8_general_ci transforma as comparações de string sem verificação de acentos, o texto “Olá” será o mesmo que “Ola”.

create table teste (expressao varchar(100)) collate 'utf8_general_ci';
insert teste (expressao) values ('Olá');

select * from teste where expressao = 'Ola';

expressao
---------
Olá

Leia também