Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Como evitar caracteres de lixo/lixo ao ler dados de vários idiomas?


O Gujarati começa રેલવે , correto? E o Malyalam inicia നേപ , correto? E o inglês deveria ter incluído Bureau’s .

Este é o caso clássico de
  • Os bytes que você tem no cliente estão codificados corretamente em utf8. (Bureau é codificado no subconjunto Ascii/latin1 de utf8; mas não é o apóstrofo ascii.)
  • Você se conectou com SET NAMES latin1 (ou set_charset('latin1') ou ...), provavelmente por padrão. (Deveria ser utf8 .)
  • A coluna na tabela foi declarada CHARACTER SET latin1 . (Ou possivelmente foi herdado da tabela/banco de dados.) (Deve ter sido utf8 .)

A correção para os dados é um "ALTER de 2 passos".
ALTER TABLE Tbl MODIFY COLUMN col VARBINARY(...) ...;
ALTER TABLE Tbl MODIFY COLUMN col VARCHAR(...) ... CHARACTER SET utf8 ...;

onde os comprimentos são suficientemente grandes e os outros "..." têm qualquer outra coisa (NOT NULL , etc) já estava na coluna.

Infelizmente, se você tiver muitas colunas para trabalhar, serão necessários muitos ALTERs. Você pode (deve) MODIFY todas as colunas necessárias para VARBINARY para uma única tabela em um par de ALTERs .

A correção para o código é estabelecer utf8 como a conexão; isso depende da api usada no PHP. Os ALTERs irá alterar a definição da coluna.

Editar

Você tem VARCHAR com o CHARACTER SET errado . Portanto, você vê Mojibake como રેલ . A maioria das técnicas de conversão tenta preservar રેલ , mas não é isso que você precisa. Em vez disso, dê um passo para VARBINARY preserva os bits enquanto ignora a antiga definição dos bits que representam caracteres codificados em latin1. A segunda etapa novamente preserva os bits, mas agora alegando que eles representam caracteres utf8.