Convertir datos de latin1 a utf8 en MySQL 5.1

domingo, 17 de mayo de 2009
Hace poco tuve que migrar el sitio web de la empresa en la cual trabajo a otro servidor para lo cual fue necesario pedir, al proveedor del servicio de hosting, el respaldo del sitio junto a la base de datos.

El problema apareció cuando los datos de la base de datos perdieron la codificación utf8, los acentos (tíldes), las ñ's y otros caracteres fueron reemplazados por caracteres extraños, por ejemplo Consultoría en vez de Consultoría.

Cuando cargué la base de datos (utilizando PhpMyAdmin) me dí cuenta que las tablas quedaron con el charset latin1 en vez de utf8. Averiguando por Internet supe que el problema está en la instalación inicial de MySQL, la cual deja todo el sistema con latin1_swedish_ci y por lo tanto al exportar la base de datos, se pierden los caracteres especiales.

En Internet abundan pequeñas guías que solo solucionan parcialmente el problema pero no del todo. En la mayoría de las páginas encontré que se debía cambiar el charset de la base de datos, tablas y campos (varchar y text), pero eso solo sirve para los datos nuevos, pero que pasa con los que ya están ingresados y que presentan el problema ?

La receta para solucionar el problema completo es seguir los siguientes pasos (en orden):

  1. Convertir los datos de latin1 a binario y de binario a utf8 para cada campo de tipo varchar y text de cada tabla de la base de datos.
  2. Cambiar el charset del campo de latin1 a utf8.
  3. Cambiar el charset de las tablas de latin1 a utf8.
  4. Cambiar el charset y el collation de la base de datos de latin1 a utf8.

Para convertir los datos de un charset a otro se utiliza la función convert de MySQL, la cual se usa de la siguiente manera:

update tabla set campo = convert( convert(campo using binary) using utf8);


Para cambiar el charset de la tabla se hace de la siguiente manera:

alter table tabla charset = utf8;


Para cambiar el charset de la base de datos se hace de la siguiente manera:

alter database basedatos charset = utf8;


Y con eso se soluciona el problema.

Para evitar que vuelva a suceder el problema en el futuro, recomiendo que sean precavidos al crear una base de datos y siempre seleccionen el charset y collation a utf8 (_unicode_ci).

Espero les sirva como a mi.

Saludos !!!

14 comentarios:

Anónimo dijo...

Hola hice lo que sugieres, pero, el resultado no fue el esperado. me cambió los acentos de "Consultoría" a "Consultori?a"

qué más puedo hacer ?

Byron Corrales dijo...

a mi me funciono perfectamente gracias :)

juanito dijo...

A mi no me funciona absolutamente nada.

Llevo unos meses intentando hacer la conversión de varias bases de datos, creo que he probado todo lo que anda por la web.

Encima cuando entro datos en una nueva base de datos con todas las variables a charset utf8 en todas sus posibilidades, en una tabla utf8, por medio de phpmyadmin o sqlyog los carácteres aparecen correctamente en phpmyadmin, sin embargo en el navegador (con o sin el meta content="text/html;utf8") me salen los caráteres "chinos").

Si hago un SELECT HEX('€') en phpmyadmin me da correctamente E282AC.

Por medio del navegador, si entro los datos a través de php, (sin utf_encode o decode, y sin ninguna conversión) los puedo visualizar correctamente en el navegador, sin embargo en phpmyadmin aparecen distorsionado.

Si no fuera que la copia de seguridad me viene con los signos bárbaros me conformaría con lo que hay, pero me temo que un día me dará problema.

He probado con varios ordenadores y sistemas operativos, es lo mismo.
El servidor es dedicado con CENTOS5, PHP5.1 y Plesk 9.1

No se si alguien tendrá idea.

juanito dijo...

Solucionado.
El error mío era de siempre intentar poner los textos en campos text en vez de blob. Supongo que los datos en utf8 se deben guardar en binary, para poder leer los correctamente en phpmyadmin o sqlyog. Creo que se debe recomendar guardar los textos en varbinary o blob.

Daniel Dario Morales Salas dijo...

yo los almaceno como varchar y funciona impecable, rara tu solucion, pero si te funcionó genial.

Saludos!!

Nicolás dijo...

Muchas gracias, me sirvió mucho realmente!!

Cristóbal dijo...

Yo tengo ese mismo problema, pero incluso en el dump ya vienen alterados esos caracteres, y por más que cambio la codificación en el editor de texto a UTF-8 sin BOM (Notepad++), no consigo resultados. También he generado la base de datos importando ese dump, haciendo los pasos que dices, pero los caracteres siguen igual.

Suponiendo que no tengo la posibilidad de generar otro dump, ¿se podrá arreglar este de alguna forma?

Saludos.

Cristóbal dijo...

Vengo a retirar lo dicho antes, pues si me funcionó. Me había comido un paso.

Gracias Daniel.

Anónimo dijo...

Hola, yo ya habia convertido todo a utf8 (archivo, configuracion, etc ) y no funcionaba, en mi caso modifiqué un poco tu solución, en vez de "convert using binary" ocupé "convert using latin1" y todo de maravilla ...

publicidad google adwords dijo...

Si agregas los tipos como varchar como comentan arriba te ahorra muchos dolores de cabeza.

Anónimo dijo...

Muchas gracias. Este método me ha funcionado perfectamente.

Anónimo dijo...

no me sirvio un poto roto hijo de puta

Anónimo dijo...

Me sirvió perfecto, pero al insertar registros con php en mysql aparecen los caracteres raros solo en las nuevas tuplas. Tendrá que ver con php ese tipo de problema?

Anónimo dijo...

Tuve q pasarlo a latin_bin luego bynary y luego utf8 y funciono perfecto …gracias me sirvió demasiado .!

Publicar un comentario en la entrada