Três lugares em que o MySQL precisa de uma codificação
- Coluna ou tabela: o conjunto de caracteres em que os dados são gravados, como
utf8mb4oulatin1. - Conexão: o conjunto de caracteres em que cliente e servidor conversam. Defina com
SET NAMES utf8mb4ou nas configurações da conexão. - Arquivo: a codificação usada para ler uma importação ou gravar uma exportação. No phpMyAdmin fica em Conjunto de caracteres do arquivo.
Se os três não combinam, os caracteres quebram. O caso mais comum: texto UTF-8 gravado por uma conexão latin1 em uma coluna latin1. O sistema parece normal, mas o phpMyAdmin e a exportação mostram ç.
Antes
"1","João Conceição","Rua São João 12","São Paulo"
Depois
"1","João Conceição","Rua São João 12","São Paulo"
Conferir os conjuntos de caracteres
SHOW VARIABLES LIKE 'character_set%';mostra as configurações de servidor e conexão.SHOW CREATE TABLE clientes;mostra o conjunto de caracteres da tabela e de suas colunas.SELECT nome, HEX(nome) FROM clientes LIMIT 5;mostra os bytes reais: em uma colunautf8mb4,C3A7é umç, enquantoC383C2A7é umçjá quebrado.
Reparar uma exportação ou um dump
- Exporte a tabela no phpMyAdmin como SQL ou CSV, ou use
mysqldump --default-character-set=utf8mb4. - Solte o arquivo na caixa acima. O Mojibuster repara só os trechos quebrados; caracteres corretos ficam como estão.
- Confira os trechos reparados em O que mudou? e baixe o arquivo.
- Importe em uma tabela
utf8mb4e escolhautf-8como conjunto de caracteres na janela de importação. - Teste antes em uma cópia, antes de substituir a tabela real.
A exportação nunca sai do seu computador, o que importa para dados de clientes. Se o texto já foi codificado duas vezes, veja antes a página sobre codificação dupla.
Resolver a causa
- Crie tabelas novas com
DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci. - Defina a conexão do seu sistema como
utf8mb4; em PHP, por exemplo, comcharset=utf8mb4no DSN do PDO. - Se há bytes UTF-8 em uma coluna
latin1, não a converta direto comCONVERT TO: isso codifica pela segunda vez e gera texto com codificação dupla. O caminho seguro passa por um tipo binário: primeiroMODIFY nome VARBINARY(255), depoisMODIFY nome VARCHAR(255) CHARACTER SET utf8mb4. - Se o MySQL troca caracteres por
?, a coluna ou a conexão não consegue representá-los. O que já foi gravado assim está perdido; mais em interrogação no lugar de acentos.
Perguntas frequentes
Por que no meu sistema aparece certo, mas no phpMyAdmin não?
Porque sistema e banco cometem o mesmo erro duas vezes: o sistema grava UTF-8 por uma conexão latin1 e lê do mesmo jeito. O phpMyAdmin conecta corretamente e por isso mostra o que realmente está gravado. Se aparecerem sequências longas como ç, veja dupla codificação e WordPress e banco de dados.
Qual collation devo usar?
utf8mb4_unicode_ci serve para a maioria dos sistemas; desde o MySQL 8, o padrão é utf8mb4_0900_ai_ci. O mais importante é o charset utf8mb4, não utf8, que no MySQL não guarda emojis.
Funciona também com MariaDB?
Sim. O MariaDB trata conjuntos de caracteres como o MySQL e os comandos são os mesmos.
Qual o tamanho máximo do dump?
Até 100 MB por arquivo. Exporte bancos maiores tabela por tabela.