| Caracteres internacionales y codificación en MySQL |
|
| Documentación - Tutoriales | |||
| Escrito por Roberto Saralegui | |||
| Sábado 19 de Septiembre de 2009 23:00 | |||
|
Por desgracia, el alojamiento gratuito de 1and1.es en el que actualmente está esta página llega a su fin; hay que prepararse para una posible migración. Así que he comprobado qué ocurriría al instalar los backups de la web (gracias sobre todo a Lazybackup) en mi servidor local: ¡huy! ¡hay un problema con alguna página de códigos o con la codificación!: "Menú principal" aparece como "Menú principal". Revisando el volcado de la base de datos MySQL, compruebo que es correcto. Está en codificación utf-8 y veo los caracteres correctamente. Entonces ¿qué está pasando? Veamos. ¿Qué ocurre si vuelvo a hacer un volcado de la base de datos local? Aparecen unas líneas nuevas al comienzo que no están en mi volcado original: -- MySQL dump 10.11 -- -- Host: localhost Database: XXXXXXXXXX -- ------------------------------------------------------ -- Server version 5.0.75-0ubuntu10.2
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!40101 SET NAMES utf8 */; /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
-- Table structure for table `jos_attachments` -- Hmmm, ese SET NAMES utf8; ni ninguno de los SET estaban en el primer volcado: # # MySQL database dump # Created by MySQL_Backup class, ver. 1.0.1 # # Host: XXXXXXXX.1and1.es # Generated: Sep 17, 2009 at 01:38 # MySQL version: 5.0.67-log # PHP version: 5.2.10 # # Database: `XXXXXXX` # # # Table structure for table `jos_attachments` # Miramos cómo está la codificación en local y en el servidor: mysql> show variables like 'character_set%'; +--------------------------+------------------------------------------------------------------+ | Variable_name | Value | +--------------------------+------------------------------------------------------------------+ | character_set_client | latin1 | | character_set_connection | latin1 | | character_set_database | utf8 | | character_set_filesystem | binary | | character_set_results | latin1 | | character_set_server | latin1 | | character_set_system | utf8 | | character_sets_dir | /usr/local/mysql-5.0.67-linux-i686-glibc23/share/mysql/charsets/ | +--------------------------+------------------------------------------------------------------+ 8 rows in set (0.00 sec) Local: mysql> show variables like 'character_set%'; +--------------------------+----------------------------+ | Variable_name | Value | +--------------------------+----------------------------+ | character_set_client | latin1 | | character_set_connection | latin1 | | character_set_database | latin1 | | character_set_filesystem | binary | | character_set_results | latin1 | | character_set_server | latin1 | | character_set_system | utf8 | | character_sets_dir | /usr/share/mysql/charsets/ | +--------------------------+----------------------------+ 8 rows in set (0.00 sec) La diferencia está en character_set_database en el servidor es utf8, pero en local es latin1. ¿Qué significa eso? Que, por defecto, mi base de datos local utiliza la codificación latin1. Como al comienzo del volcado que utilizo para cargar los datos no hay ningun parámetro que lo ajuste, está tomando la codificación por defecto. Pero ese volcado está codificado en utf8. ¿Resultado? El típico lío de confusión entre charsets que hace que tengamos el feo "Menú principal". ¿Solución? Añadir al comienzo del volcado una línea explicitando la codificación: SET NAMES utf8 ; Y si somos un poco más exquisitos, lo hacemos con una expresión condicional para que no se ejecute con versiones anteriores a la 4.01: /*!40101 SET NAMES utf8 */; ¿Qué enseñanza sacamos de esto? Primera, que si manejamos información en un idioma diferente del inglés, tenemos siempre que estar atentos a la codificación de nuestros caracteres especiales. Y la segunda y más importante: siempre hay que probar los backups.
|