Tres sitios donde MySQL necesita una codificación
- Columna o tabla: el juego de caracteres en que se guardan los datos, como
utf8mb4olatin1. - Conexión: el juego de caracteres en que hablan cliente y servidor. Se fija con
SET NAMES utf8mb4o en los ajustes de conexión. - Archivo: la codificación con que se lee una importación o se escribe una exportación. En phpMyAdmin está en Juego de caracteres del archivo.
Si los tres no coinciden, los caracteres se rompen. El caso más habitual: texto UTF-8 escrito por una conexión latin1 en una columna latin1. La aplicación se ve bien, pero phpMyAdmin y la exportación muestran ñ.
Antes
"1","José Muñoz","Calle Alcalá 12","Málaga"
Después
"1","José Muñoz","Calle Alcalá 12","Málaga"
Comprobar los juegos de caracteres
SHOW VARIABLES LIKE 'character_set%';muestra los ajustes de servidor y conexión.SHOW CREATE TABLE clientes;muestra el juego de caracteres de la tabla y de sus columnas.SELECT nombre, HEX(nombre) FROM clientes LIMIT 5;muestra los bytes reales: en una columnautf8mb4,C3B1es unañ, mientras queC383C2B1es unñya roto.
Reparar una exportación o un volcado
- Exporta la tabla en phpMyAdmin como SQL o CSV, o con
mysqldump --default-character-set=utf8mb4. - Suelta el archivo en el cuadro de arriba. Mojibuster repara solo los puntos rotos; los caracteres correctos no se tocan.
- Revisa los cambios en ¿Qué ha cambiado? y descarga el archivo.
- Impórtalo en una tabla
utf8mb4y eligeutf-8como juego de caracteres en el diálogo de importación. - Prueba primero con una copia antes de sustituir la tabla real.
La exportación no sale de tu equipo, algo importante con datos de clientes. Si usas WordPress, para los datos serializados mira antes la página de codificación doble.
Corregir la causa
- Crea las tablas nuevas con
DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci. - Pon la conexión de tu aplicación en
utf8mb4; en PHP, por ejemplo, concharset=utf8mb4en el DSN de PDO. - Si hay bytes UTF-8 en una columna
latin1, no la conviertas directamente conCONVERT TO: se codifica por segunda vez y aparece texto con codificación doble. El camino seguro pasa por un tipo binario: primeroMODIFY nombre VARBINARY(255)y luegoMODIFY nombre VARCHAR(255) CHARACTER SET utf8mb4. - Si MySQL sustituye caracteres por
?, la columna o la conexión no pueden representarlos. Lo que ya se guardó así se ha perdido; más en signos de interrogación en vez de acentos.
Preguntas frecuentes
¿Por qué en mi aplicación se ve bien y en phpMyAdmin no?
Porque aplicación y base de datos cometen el mismo error dos veces: la aplicación escribe UTF-8 por una conexión latin1 y lo lee igual. phpMyAdmin se conecta bien y por eso muestra lo que realmente está guardado. Si además ves secuencias largas como ó, consulta doble codificación y WordPress y bases de datos.
¿Qué cotejamiento (collation) debo usar?
utf8mb4_unicode_ci sirve para la mayoría de las aplicaciones; desde MySQL 8 el predeterminado es utf8mb4_0900_ai_ci. Lo más importante es el juego de caracteres utf8mb4, no utf8, que en MySQL no guarda emojis.
¿Funciona también con MariaDB?
Sí. MariaDB gestiona los juegos de caracteres como MySQL y los comandos son los mismos.
¿Qué tamaño puede tener el volcado?
Hasta 100 MB por archivo. Las bases de datos más grandes, expórtalas tabla por tabla.