Ir al contenido principal

MySQL Latin1 a UTF-8

Existe muchos documentos en Internet de como migrar una base de datos de MySQL con codificación ISO-8859-1 a UTF-8, el hecho de que algún método funcione o no, puede depender de muchos factores.

"Lo mas importante es entender lo que se esta haciendo."

Los factores a tomar en cuenta son.
Apache: Por default entrega las paginas ISO-8859-1 (Latin1)
  • Se puede modificar esto con la variable "AddDefaultCharset UTF-8" en el archivo de configuración de apache default-server.conf o agregando esta variable al archivo .htaccess en el directorio raiz de la aplicacion web.
    • O agregar los encabezados correspondientes a nuestras aplicaciones web.
    1. HTML: <meta charset="utf8">
    2. PHP: header ('Content-type: text/html; charset=utf-8');
    3. PERL: print "Content-Type: text/html; charset=utf-8\n\n";
    En este enlace se puede verificar que codigo de caracteres esta usando nuestra aplicación web.


    MySQL: Revisar si se esta usando el set de caracteres UTF8

    # mysql -u root -p
    mysql> show variables like 'char%';



    Migración de la base de datos vía la consola linux.

    Método 1: En este ejemplo se asume que nuestra base de datos y nuestros datos en si utilizaban una codificación ISO-8859-1 (latin1), aunque se puede dar el caso de que desconozcamos completamente el set de caracteres que se utilizaban.

    Respaldar la base de datos.

    # mysqldump --opt --routines -u root -p --default-character-set=latin1 mibase > mibase_latin1.sql

    Entramos a la consola de MySQL.

    # mysql -u root -p

    Borramos la base de datos.

    mysql> drop database mibase;

    NOTA: Si no podemos usar la base de datos por estar en producción podemos usar cualquier otra base de datos hasta estar seguros de que funciona correctamente nuestra migración.

    Creamos una nueva base de Datos, con el set de caracteres UTF-8.

    mysql> CREATE DATABASE mibase CHARACTER SET utf8 COLLATE utf8_general_ci;

    Desde la linea de comandos convertimos nuestro archivo de respaldo a UTF-8

    # iconv -f ISO-8859-1 -t UTF-8 mibase_latin1.sql > mibase_utf8.sql

    Remplazar la variable CHARSET=latin1 por CHARSET=utf8 dentro del archivo mibase_utf8.sql desde la linea de comandos.

    # perl -pi -w -e 's/CHARSET=latin1/CHARSET=utf8/g;' mibase_utf8.sql

    Con el comando file podemos verificar si el archivo mibase_utf8.sql realmente es un archivo UTF-8.


    Cargamos nuestro archivo UTF-8 a nuestra nueva base de datos.

    # mysql -u root -p --default_character_set utf8 mibase < mibase_utf8.sql

    Entramos en la consola de MySQL y hacemos un volcado de una tabla para ver si los datos son desplegados correctamente.

    # mysql -u root -p

    mysql> use mibase;

    mysql> select * from tarpropiedad;
    ...
    ...
    ...

    Si los acentos se despliegan bien, la migración de la base de datos se puede considerar exitosa.

    En nuestro ejemplo podemos ver que en el volcado de la tabla los acentos no se despliegan correctamente a pesar de haber convertido todo a UTF-8.

    El problema en este caso es que nuestra base de datos si estaba codificada en ISO-8859-1(latin1), pero nuestros datos fueron almacenados en UTF-8, por lo que pasamos al segundo Método.

    Método 2: La base de datos esta configurada en ISO-8859-1(latin1), pero los datos se almacenaron en UTF-8.

    Borramos nuestra nueva base de datos UTF-8 y comenzamos desde el principio.

    # mysql -u root -p

    mysql> drop database mibase;

    Creamos una nueva base de datos, con el set de caracteres UTF-8.

    mysql> CREATE DATABASE mibase CHARACTER SET utf8 COLLATE utf8_general_ci;

    Usamos el mismo archivo de respaldo mibase_latin1.sql

    En esta ocasion no convertimos a UTF8 nuestro archivo de respaldo.

    Solo remplazamos la variable CHARSET=latin1 por CHARSET=utf8 dentro del archivo mibase_latin1.sql desde la linea de comandos.

    # perl -pi -w -e 's/CHARSET=latin1/CHARSET=utf8/g;' mibase_latin1.sql

    Cargamos nuestro archivo de respaldo mibase_latin1.sql a nuestra nueva base de datos.

    # mysql -u root -p --default_character_set utf8 mibase < mibase_latin1.sql

    Entramos nuevamente a la consola de MySQL y hacemos un volcado de una tabla para ver si los datos son desplegados correctamente.

    # mysql -u root -p

    mysql> use mibase;
    mysql> select * from tarpropiedad;
    ...
    ...
    ...

    En este ejemplo podemos ver que los datos son desplegados correctamente.

    Ahora probamos nuestra aplicación para ver el correcto desplegado de datos vía web, al parecer todo esta correcto los acentos se despliegan correctamente.


    Sin embargo al hacer una consulta de una tabla diferente. Los datos están llenos de basura.


    El problema son los campos BLOB, en este ejemplo no convertimos nuestro archivo de respaldo a UTF-8 y los campos BLOB no almacenaron la información en UTF-8 y conservaron la codificación ISO-8859-1(latin1).

    Si tenemos tablas con muchos campos texto que incluyan algún campo BLOB, esto si puede ser un problema serio hay algunos métodos de convertir todos los campos a binarios, pero se necesita estar concentrado en lo que se esta haciendo.

    Aquí hay una liga donde usan este método.

    En mi caso las tablas que usan campos BLOB contienen algunos otros campos pero  son usados para claves o indices y no hay ningún tipo de carácter especial.

    Por lo que puedo convertir cada tabla UTF-8 manualmente.

    Método 3: Este método es la continuación del Método 2, pero solo se convertirán  tablas con campos BLOB a UTF-8.

    Respaldamos nuestra tabla. 

    # mysqldump --opt --routines -u root -p --default-character-set=latin1 mibase tieclientes > tieclientes_latin1.sql

    Desde la linea de comandos convertimos nuestro archivo de respaldo a UTF-8

    # iconv -f ISO-8859-1 -t UTF-8 tieclientes_latin1.sql > tieclientes_utf8.sql

    Remplazar la variable CHARSET=latin1 por CHARSET=utf8 dentro del archivo tieclientes_utf8.sql 

    # perl -pi -w -e 's/CHARSET=latin1/CHARSET=utf8/g;' tieclientes_utf8.sql

    Cargamos nuestro archivo UTF-8 a la base de datos.

    # mysql -u root -p --default-character-set utf8 mibase < tieclientes_utf8.sql
     
    Repetimos el proceso para cada tabla con campos BLOB.

    Nuevamente probamos nuestra aplicación para ver el correcto desplegado de datos vía web, hacemos una consulta a una tabla con campos BLOB.


    En este momento podemos decir que la migración fue un éxito, los acentos se despliegan correctamente.

    En resumen:  

    Cualquier método que encontremos en Internet debe de funcionar solo que al hacer la migración debemos de estar muy atentos para detectar exactamente en que parte, fallo nuestra migración.


    Comentarios

    Entradas populares de este blog

     Extensiones Remotas Issabel PBX

    Extensiones Remotas Issabel/Elastix Usar extensiones Remotas En Issabel PBX no es complicado, pero si debemos de considerar varios puntos, para tener extensiones remotas con una buena calidad de voz y sin olvidarse de la seguridad. La configuración es aplicable para instalaciones en servidores Elastix, solo que la configuración de Fail2Ban se debe de hacer manualmente desde la consola de Linux. Internet  No importa si es una extensión o varias a configurar siempre hay que tener en cuenta que si usamos el mismo enlace para navegar, los canales de voz perderán ante los protocolos de navegación como http, ftp etc. Por lo que tendremos una mala calidad en nuestras llamadas, por ejemplo voz entrecortada. Nota: Algunos clientes en la PC hacen descargas de archivos tomando todo el ancho de banda disponible, afectando la calidad de voz. Seguridad Ante las experiencias que se vivieron con Elastix y VtigerCRM, muchos ya no intentaron publicar su PBX en Internet, el hackeo a sus PBX solo toma...

    Let’s Encrypt certificados Gratis en Linux - SSL/TLS con certbot para APACHE, POSTFIX y DOVECOT.

    Certificado SSL/TLS con Certbot APACHE, POSTFIX, y DOVECOT Let’s Encrypt nos permite obtener Certificados gratis con una duración aproximadamente de 3 meses, pero es muy fácil renovar, y si no hay cambios de dominios en nuestros servidores se puede automatizar con un simple cron. En esta ocasión se usara la herramienta certbot es un cliente ACME, el cual permite controlar y verificar los nombres de dominio, hay varios clientes ACME se pueden revisar en la pagina de  Let’s Encrypt   El cliente de certbot puede estar ya incluido en la distribucion Linux. Por ejemplo para instalarlo en OpenSuse Leap 15.1 # zypper install python3-certbot Si tienes problemas para instalar en tu distribución linux, puedes hacerlo vía snap, en la pagina de  certbot  hay varios tips de como instarlo y usarlo. APACHE (HTTPS 443) Generalmente ya se cuenta con servidor configurado con https apuntando con uno o mas dominios al servidor. Por lo que solo hay que correr certbot y el...

    Configurar DynDNS desde la Consola en EdgeRouter Lite Ubiquiti

    Configurar DynDNS desde la Consola en EdgeRouter Lite Ubiquiti Firmware 1.6 Configurar DynDNS no es nada complicado desde la interfaz Web del Router Ubiquiti. Ir a  Services ==> DNS ==>  Dynamic DNS ==>  Add New Seleccionar nuestra interface conectada a Internet, el servicio que usaremos(dyndns), hostname, usuario y contraseña. Sin embargo en versiones 1.6  EdgeOS firmware, había bugs que hacia que no funcionara correctamente la actualización de la IP publica en DynDNS, por lo que  es bueno saber como configurar DynDNS vía consola. Corregir Bug. Nos conectamos a la consola del Router Ubiquiti ssh ubnt@192.168.45.254 Editamos el script, para corregir  el problema de que no actualiza la ip IP publica en Dyndns. $ sudo -u root vi /opt/vyatta/sbin/vyatta-dynamic-dns.pl Comentar la siguiente linea, aproximadamente en la linea 107. # $output .= "use=if, if=$interface\n\n\n"; Y agregar la siguiente linea. $output .= "use=web, web=checkip.dynd...