Lidiando con UTF-8 y bases de datos en MySQL™.
Introducción.
UTF-8
UTF-8 es un método de codificación de ASCII para Unicode (ISO-10646), el Conjunto de Caracteres Universal o UCS. Éste codifica la mayoría de los sistemas de escritura del mundo en un solo conjunto de caracteres, permitiendo la mezcla de lenguajes y guiones en un mismo documento sin la necesidad de ajustes para realizar los cambios de conjuntos de caracteres. |
Cualquier sitio de red que haga uso de bases de datos suele toparse con problemas cuando se trata de lidiar con el tipo de codificación (UTF-8, ISO-8859-1, etc.), puesto que en algunos casos, por citar un ejemplo, los caracteres latinos se muestran incorrectamente por el cambio de codificación.
Actualmente se está adoptando UTF-8 como codificación para todo, sin embargo aún hay mucho material codificado en, por ejemplo, ISO-8859-1, e incluso en algunos casos codificado de manera poco apropiada para los latinos (KOI8-R alias cirílico).
Uno de los casos que podemos citar es PHP Nuke. Si se descarga el código fuente de cualquier versión de PHP Nuke y se examina el tipo de codificación, encontraremos que casi todos los fichero PHP y el molde de la base de datos inicial, nuke.sql, están codificados en ISO-8859-1, aunque Bluefish los vea como KOI8-R (alias cirílico). Utilizar nuke.sql con esta codificación tiene como consecuencia el que todos los datos que se almacenen en la base de datos también estarán codificados en ISO-8859-1. Esto puede no ser un problema serio para la mayoría, puesto que han utilizado esta codificación durante años. Pero cuando se actualiza un sistema operativo o se cambia de proveedor de servicio de hospedaje donde ya se adoptó UTF-8, es cuando surgen los problemas.
Procedimientos.
La primera recomendación a quien vaya a implementar un sitio con PHP Nuke, al igual que cualquier otro tipo de software similar, sería tomar nuke.sql y convertirlo a UTF-8, o cualquier otra codificació según el caso y conveniencia. Para términos generales, puede utilizarse Bluefish para realizar este cambio de codificación, aunque quienes prefieran una consola podrán utilizar Vi para realizar esta tarea:
$ vi -c ":wq! ++enc=utf8" nuke.sql
Recomendamos utilizar Vi debido a que éste no solo codificará el fichero, a diferencia de Bluefish y iconv —usualmente utilizados para este fin— también convertirá los conjuntos de caracteres a UTF-8 sin pérdida alguna.
Tomar esta precaución asegurará que los datos que se almacenen en UTF-8 en la base de datos. Sin embargo… ¿Que se puede hacer cuando se tiene una gran base de datos en producción? Puede seguirse el siguiente procedimiento:
- Obtener un respaldo de la base de datos actual:
$ mysqldump -uusuario -pcontraseña -hservidor base-de-datos > respaldo.sql
→ Como precacución, archive este resplado en un lugar seguro por si acaso sale algo mal.
- Utilizar vi para codificar en UTF y caracteres, de modo que no se pierda un solo carcater:
$ vi -c ":saveas! ++enc=utf8 respaldo-utf8.sql" respaldo.sql
Lo anterior hace que vi abra respaldo.sql y lo guarde como respaldo-utf8.sql realizando al mismo tiempo la codificación en UTF-8.
Si se tienen varios ficheros *.sql, aún si es tentador a fin de ahorrar trabajo, no es conveniente ejecutar vi -c ":wq! ++enc=utf8" *.sql, ya que solo se codificará sin convertir los caracteres. Puede utilizarse un guión ejecutable con un bucle para tal finalidad:
#!/bin/sh
for f in *.sql;
do
vi -c "wq! ++enc=utf8" $f
done
- Una vez codificado todo es conveniente crear una una nueva base de datos que denominaremos «temporal» para realizar pruebas y verificar que el método ha dado resultado:
$ su - root
# mysqladmin -p create temporal
# mysql -p
mysql> GRANT all ON temporal.* TO usuario@localhost IDENTIFIED BY 'contraseña';
mysql> exit;
# exit
- Utilizaremos respaldo.sql —ya convertido a UTF-8— sobre la base de datos anteriormente creada:
$ mysql -uusuario -pcontraseña temporal < respaldo-utf8.sql
- Una vez hecho lo anterior, realice pruebas y verifique que los caracteres latinos contenidos entre los datos que aparecen la base de datos realmente se visualizan correctamente. Si está conforme y considera que todo está correcto, a su discreción, proceda a reemplazar la base de datos, previo respaldo por mera precaución.
$ mysqldump -uusuario -pcontraseña -hservidor base-de-datos > nuevo-respaldo.sql
$ mysql -uusuario -pcontraseña -hservidor base-de-datos < respaldo-utf8.sql |