Cambiar MySQL a utf8mb4: Guía de migración y solución de problemas

1. Introducción

Por qué es necesario cambiar el conjunto de caracteres de MySQL

El conjunto de caracteres de una base de datos es una configuración crucial que determina cómo se codifican y procesan los caracteres de los datos almacenados. En MySQL, el conjunto de caracteres predeterminado suele ser latin1, lo que puede causar problemas al manejar datos que incluyen caracteres japoneses u otros caracteres especiales. Especialmente durante la migración de datos o la unificación de sistemas, cambiar a un conjunto de caracteres apropiado es importante.

Problemas comunes y sus causas

Los problemas típicos relacionados con los conjuntos de caracteres de MySQL incluyen los siguientes.

  1. Desorden de caracteres
  • utf8 y latin1 están mezclados
  • Las configuraciones de conjunto de caracteres del cliente y del servidor difieren
  1. Problemas relacionados con la búsqueda
  • Las diferencias en la intercalación impiden obtener los resultados de búsqueda deseados
  • El orden de clasificación difiere de las expectativas
  1. Problemas de migración de datos
  • Debido a que no se utiliza utf8mb4, los emojis y símbolos especiales no se pueden almacenar
  • La conversión de conjuntos de caracteres no se realiza correctamente durante la exportación/importación de datos

Propósito y estructura de este artículo

Este artículo ofrece una guía completa sobre los cambios de conjunto de caracteres en MySQL, cubriendo conocimientos básicos, cómo cambiarlo y solución de problemas.

Flujo del artículo

  1. Conocimientos básicos sobre los conjuntos de caracteres de MySQL
  2. Cómo comprobar el conjunto de caracteres actual
  3. Cómo cambiar el conjunto de caracteres de MySQL
  4. Solución de problemas después del cambio
  5. Impacto de los cambios de conjunto de caracteres en el rendimiento
  6. Configuraciones recomendadas (mejores prácticas)
  7. Preguntas frecuentes (FAQ)

Al leer esta guía, profundizarás en tus conocimientos sobre los conjuntos de caracteres de MySQL y podrás elegir configuraciones adecuadas y evitar problemas.

2. Conjuntos de caracteres de MySQL: comprensión básica

¿Qué es un conjunto de caracteres (Character Set)?

Conjunto de caracteres (Character Set) es la regla que se utiliza al almacenar y procesar caracteres como datos digitales. Por ejemplo, al almacenar el carácter japonés “あ”, UTF-8 lo representa como la secuencia de bytes E3 81 82, mientras que Shift_JIS utiliza 82 A0. MySQL permite especificar diferentes conjuntos de caracteres para cada base de datos o tabla, y elegir el conjunto de caracteres adecuado ayuda a prevenir textos desordenados y facilita la internacionalización del sistema.

Conjuntos de caracteres comunes

Conjunto de caracteres

Características

Casos de uso

utf8

UTF-8 hasta 3 bytes

No admite algunos caracteres especiales (por ejemplo, emojis)

utf8mb4

4-byte UTF-8

Soporta emojis y caracteres especiales (recomendado)

latin1

ASCII compatible

Usado en sistemas heredados

¿Qué es la intercalación (Collation)?

Intercalación define las reglas para comparar y ordenar datos utilizando un conjunto de caracteres. Por ejemplo, determina si “A” y “a” se consideran iguales y cómo se ordenan los caracteres.

Intercalaciones comunes

Collation

Descripción

utf8_general_ci

Insensible a mayúsculas/minúsculas, adecuado para uso general

utf8_unicode_ci

Ordenación basada en el estándar Unicode (recomendado)

utf8mb4_bin

Comparación binaria (utilizado cuando se requieren coincidencias exactas)

Diferencias entre utf8 y utf8mb4

El utf8 de MySQL puede almacenar realmente solo caracteres de hasta 3 bytes, por lo que no puede manejar algunos caracteres especiales (como emojis o caracteres chinos extendidos). En contraste, utf8mb4 puede usar hasta 4 bytes, y su uso se recomienda para aplicaciones modernas.

Conjunto de caracteres

Bytes máximos

Soporte de Emoji

Recomendación

utf8

3 bytes

❌ No soportado

❌ No recomendado

utf8mb4

4 bytes

✅ Soportado

✅ Recomendado

Razones para cambiar de utf8 a utf8mb4

  1. Compatibilidad futura: En sistemas modernos, utf8mb4 está convirtiéndose en el estándar.
  2. Almacenamiento de caracteres especiales y emojis: Usar utf8mb4 garantiza que puedas manejar datos de publicaciones en redes sociales y aplicaciones de mensajería de forma segura.
  3. Soporte para internacionalización: Reduce el riesgo de textos desordenados al construir sistemas multilingües.

Resumen

  • Conjunto de caracteres (Character Set) determina cómo se almacenan y procesan los datos.
  • Intercalación define las reglas para comparar caracteres.
  • El utf8 de MySQL realmente admite solo hasta 3 bytes, por lo que se recomienda usar utf8mb4.
  • utf8mb4_unicode_ci es la intercalación recomendada para uso general.

3. Cómo comprobar el conjunto de caracteres actual

Antes de cambiar el conjunto de caracteres de MySQL, es importante verificar la configuración actual. Dado que puedes establecer diferentes conjuntos de caracteres para cada base de datos, tabla y columna, comprende en qué nivel se necesita un cambio.

Cómo comprobar el conjunto de caracteres actual

Verificar el conjunto de caracteres general del servidor MySQL

Primero, verifica la configuración del conjunto de caracteres predeterminado para todo el servidor MySQL.

SHOW VARIABLES LIKE 'character_set%';
SHOW VARIABLES LIKE 'collation%';

Ejemplo de salida:

+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8mb4                    |
| character_set_connection | utf8mb4                    |
| character_set_database   | utf8mb4                    |
| character_set_filesystem | binary                     |
| character_set_results    | utf8mb4                    |
| character_set_server     | utf8mb4                    |
| character_set_system     | utf8                        |
+--------------------------+----------------------------+

Verificar el conjunto de caracteres por base de datos

Para verificar el conjunto de caracteres de una base de datos específica, use el siguiente comando.

SELECT SCHEMA_NAME, DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME
FROM information_schema.SCHEMATA
WHERE SCHEMA_NAME = 'database_name';

Salida de ejemplo

+----------------+----------------------+----------------------+
| SCHEMA_NAME    | DEFAULT_CHARACTER_SET_NAME | DEFAULT_COLLATION_NAME |
+----------------+----------------------+----------------------+
| my_database   | utf8mb4               | utf8mb4_unicode_ci   |
+----------------+----------------------+----------------------+

Verificar el conjunto de caracteres de la tabla

Cómo verificar el conjunto de caracteres de una tabla específica.

SHOW CREATE TABLE table_name;

Salida de ejemplo

CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `email` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci;

Lista de verificación

  • DEFAULT CHARSET=latin1 → no es utf8mb4, por lo que debe cambiarse
  • COLLATE=latin1_swedish_ci → cambiar a utf8mb4_unicode_ci es más apropiado

Verificar el conjunto de caracteres de la columna

Para investigar el conjunto de caracteres de una columna específica, ejecute el siguiente SQL.

SELECT COLUMN_NAME, CHARACTER_SET_NAME, COLLATION_NAME 
FROM information_schema.COLUMNS 
WHERE TABLE_SCHEMA = 'database_name' 
AND TABLE_NAME = 'table_name';</> Example output
+-------------+--------------------+----------------------+
| COLUMN_NAME | CHARACTER_SET_NAME | COLLATION_NAME       |
+-------------+--------------------+----------------------+
| name        | latin1             | latin1_swedish_ci    |
| email       | utf8mb4            | utf8mb4_unicode_ci   |
+-------------+--------------------+----------------------+

En este caso, la columna name está usando latin1, por lo que se recomienda cambiarla a utf8mb4.

Resumen

  • El conjunto de caracteres de MySQL se configura en múltiples niveles (servidor, base de datos, tabla, columna)
  • Al verificar el conjunto de caracteres en cada nivel, puede realizar cambios apropiados
  • Use comandos como SHOW VARIABLES y SHOW CREATE TABLE para comprender a fondo la configuración actual

4. Cómo cambiar el conjunto de caracteres de MySQL

Al cambiar correctamente el conjunto de caracteres de MySQL, puede evitar textos distorsionados y manejar el soporte multilingüe sin problemas. En esta sección, explicaremos cómo cambiar los conjuntos de caracteres a nivel de servidor, base de datos, tabla y columna de manera ordenada.

Cambiar el conjunto de caracteres predeterminado a nivel de servidor

Para cambiar el conjunto de caracteres predeterminado a nivel de servidor, debe editar el archivo de configuración de MySQL (my.cnf o my.ini).

Pasos

  1. Abrir el archivo de configuración
  • En Linux: bash sudo nano /etc/mysql/my.cnf
  • En Windows:
    • Abrir C:ProgramDataMySQLMySQL Server X.Xmy.ini
  1. Agregar o modificar la configuración del conjunto de caracteres Agregue o modifique lo siguiente en la sección mysqld.
   [mysqld]
   character-set-server=utf8mb4
   collation-server=utf8mb4_unicode_ci
  1. Reiniciar MySQL
   sudo systemctl restart mysql

En Windows:

   net stop MySQL && net start MySQL
```%

4. **Verificar después de los cambios**

SHOW VARIABLES LIKE ‘character_set_server’;

### Cambiar el conjunto de caracteres a nivel de base de datos

ALTER DATABASE mydatabase CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

#### **Verificación después del cambio**

SELECT SCHEMA_NAME, DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME FROM information_schema.SCHEMATA WHERE SCHEMA_NAME = ‘mydatabase’;

### Cambiar el conjunto de caracteres a nivel de tabla

ALTER TABLE users CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

#### **Verificación después del cambio**

SHOW CREATE TABLE users;

### Cambiar el conjunto de caracteres a nivel de columna

ALTER TABLE users MODIFY COLUMN name VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

#### **Verificación después del cambio**

SELECT COLUMN_NAME, CHARACTER_SET_NAME, COLLATION_NAME FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = ‘mydatabase’ AND TABLE_NAME = ‘users’;

### Verificación después de los cambios y la importancia de las copias de seguridad

Para mantener la integridad de los datos después de cambiar el conjunto de caracteres, siga estos pasos.

#### **Copia de seguridad de datos**

mysqldump -u root -p –default-character-set=utf8mb4 mydatabase > backup.sql

#### **Reconfirmar la configuración**

SHOW VARIABLES LIKE ‘character_set%’; SHOW VARIABLES LIKE ‘collation%’; SHOW CREATE TABLE users;

#### **Agregar y mostrar datos de prueba**

INSERT INTO users (name, email) VALUES (‘Test User’, ‘test@example.com’); SELECT * FROM users;

### Resumen

* **Cambio de conjunto de caracteres a nivel de servidor** : Editar `my.cnf` y establecer `character-set-server=utf8mb4`
* **Cambio de conjunto de caracteres de la base de datos** : `ALTER DATABASE mydatabase CHARACTER SET utf8mb4`
* **Cambio de conjunto de caracteres de la tabla** : `ALTER TABLE users CONVERT TO CHARACTER SET utf8mb4`
* **Cambio de conjunto de caracteres de la columna** : `ALTER TABLE users MODIFY COLUMN name VARCHAR(255) CHARACTER SET utf8mb4`
* **Después de los cambios, siempre verifique la configuración y pruebe los datos**

## 5. Solución de problemas después de cambiar la codificación de caracteres

Después de cambiar el conjunto de caracteres de MySQL, hay casos en los que no funciona correctamente o los datos se corrompen. En esta sección, explicaremos en detalle los **problemas comunes y sus soluciones**.

### Causas de texto corrupto y cómo abordarlas

Si ocurre **texto corrupto** después de cambiar el conjunto de caracteres, las siguientes causas son posibles.

Causa

Método de verificación

Solution

La configuración del conjunto de caracteres del cliente difiere

SHOW VARIABLES LIKE 'character_set_client';

Ejecutar SET NAMES utf8mb4;

Los datos antes del cambio se almacenaron en una codificación diferente

SELECT HEX(column_name) FROM table_name; CONVERT()

La codificación en el momento de la conexión no es apropiada

Conectar con mysql --default-character-set=utf8mb4

Cambiar la configuración del juego de caracteres del lado del cliente

Los ajustes del lado de la aplicación para PHP, Python, etc. son incorrectos.

mysqli_set_charset($conn, 'utf8mb4');

Estandarizar la configuración del conjunto de caracteres de la aplicación

#### **Solución 1: Configurar correctamente el conjunto de caracteres del cliente**

SET NAMES utf8mb4;

#### **Solución 2: Convertir correctamente los datos previos al cambio**

UPDATE users SET name = CONVERT(CAST(CONVERT(name USING latin1) AS BINARY) USING utf8mb4);

### Consideraciones posteriores al cambio de `latin1` a `utf8mb4`

**Procedimiento seguro**

1. **Realizar una copia de seguridad de los datos actuales**

mysqldump -u root -p –default-character-set=latin1 mydatabase > backup.sql

2. **Cambiar el conjunto de caracteres de la base de datos**

ALTER DATABASE mydatabase CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

3. **Cambiar el conjunto de caracteres de la tabla**

ALTER TABLE users CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

4. **Reimportar los datos**

mysql -u root -p –default-character-set=utf8mb4 mydatabase < backup.sql

### Los datos no se pueden buscar correctamente después del cambio

#### **Caso 1: Búsqueda LIKE no funciona**

SELECT * FROM users WHERE name COLLATE utf8mb4_unicode_ci LIKE ‘%Tanaka%’;

#### **Caso 2: Orden de clasificación cambiado**

SELECT * FROM users ORDER BY BINARY name;

### Medidas en el lado de la aplicación

#### **Para PHP**

mysqli_set_charset($conn, ‘utf8mb4’);

#### **Para Python (MySQL Connector)**

import mysql.connector

conn = mysql.connector.connect( host=»localhost», user=»root», password=»password», database=»mydatabase», charset=»utf8mb4″ )

#### **Para Node.js (MySQL2)**

const mysql = require(‘mysql2’);

const connection = mysql.createConnection({ host: ‘localhost’, user: ‘root’, password: ‘password’, database: ‘mydatabase’, charset: ‘utf8mb4’ });

### Resumen

* **Los problemas que surgen después de cambiar el juego de caracteres pueden clasificarse en tres áreas: configuraciones del cliente, conversión de datos y configuraciones de la aplicación.**
* **Para evitar texto ilegible, unifique el juego de caracteres del lado del cliente con `SET NAMES utf8mb4`.**
* **Tenga en cuenta los cambios en las búsquedas LIKE y el orden de clasificación, y especifique `COLLATE` según sea necesario.**
* **Configurar `utf8mb4` en el lado de la aplicación también evita incompatibilidades de codificación.**

## 6. Impacto de los cambios de juego de caracteres en el rendimiento

Al cambiar el juego de caracteres de MySQL a `utf8mb4`, existen varias consideraciones de rendimiento, como **aumento del uso de almacenamiento** e **impacto en los índices**.  
Esta sección explica **los efectos de los cambios de juego de caracteres y las medidas óptimas**.

### Aumento del uso de almacenamiento debido al cambio de juego de caracteres

`utf8mb4` utiliza hasta **4 bytes por carácter** en comparación con el tradicional `utf8`, por lo que **el tamaño total de los datos de la tabla puede aumentar**.

#### **Bytes por carácter para cada juego de caracteres**

Conjunto de caracteres

Bytes máximos por carácter

latin1

1 byte

utf8

3 bytes

utf8mb4

4 bytes

Por ejemplo, en `utf8` un `VARCHAR(255)` puede ocupar hasta **765 bytes (255×3)**, mientras que en `utf8mb4` puede ocupar hasta **1020 bytes (255×4)**. #### **Solución**

ALTER TABLE posts MODIFY COLUMN title VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

### Aumento del tamaño del índice

En MySQL, existe un **límite en el tamaño máximo de la clave de índice**.  
Cambiar a `utf8mb4` hace que los índices sean más grandes, y existe un **riesgo de que los índices se vuelvan inutilizables**.

#### **Verificar el impacto en el índice**

SHOW INDEX FROM users;

**Error de ejemplo**

ERROR 1071 (42000): Specified key was too long; max key length is 767 bytes

#### **Solución**

ALTER TABLE users MODIFY COLUMN email VARCHAR(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

### Impacto en el rendimiento de las consultas

Cambiar el juego de caracteres a `utf8mb4` puede **afectar la velocidad de ejecución de las consultas**.

#### **Operaciones que pueden verse afectadas**

* **Búsquedas LIKE que contienen grandes cantidades de datos**
* **Procesamiento de ORDER BY**
* **Rendimiento de consultas JOIN**

#### **Solución**

CREATE INDEX idx_name ON users(name(100));

### Uso de memoria y ajuste del tamaño del búfer

Cambiar a `utf8mb4` puede **aumentar el consumo de memoria**.

#### **Configuraciones recomendadas**
[mysqld] innodb_buffer_pool_size = 1G query_cache_size = 128M

### Resumen

* **Cambiar a `utf8mb4` aumenta el uso de almacenamiento**
* **El tamaño del índice crece y puede superar los límites**
* **El rendimiento de las consultas puede verse afectado**
* **El uso de memoria aumenta, requiriendo ajustes en el tamaño del búfer**

## 7. Configuraciones recomendadas (mejores prácticas)

Al configurar los juegos de caracteres de MySQL de manera adecuada, puede mantener la integridad de los datos mientras optimiza el rendimiento.  
En esta sección, introduciremos específicamente las configuraciones recomendadas de juegos de caracteres para MySQL y explicaremos los puntos clave para una configuración óptima.

### Configuraciones recomendadas de juegos de caracteres de MySQL

Item

Configuración recomendada

Razón

Conjunto de caracteres

utf8mb4

Puede manejar todos los caracteres Unicode, incluidos emojis y símbolos especiales.

Collation

utf8mb4_unicode_ci

Insensible a mayúsculas y minúsculas y adecuado para soporte multilingüe

Motor de Almacenamiento

InnoDB

Ofrece un buen equilibrio de rendimiento e integridad

Longitud de la cadena de índice

VARCHAR(191)

Se mantiene dentro de los límites de longitud de índice de MySQL

### Configuraciones recomendadas de `my.cnf` #### **1. Configuraciones de juego de caracteres del servidor MySQL**
[mysqld] character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci init-connect=’SET NAMES utf8mb4′ skip-character-set-client-handshake innodb_large_prefix = ON innodb_file_format = Barracuda innodb_file_per_table = 1 innodb_buffer_pool_size = 1G query_cache_size = 128M

#### **2. Configuraciones de juego de caracteres del lado del cliente**
[client] default-character-set = utf8mb4

### Configuraciones recomendadas de la base de datos

CREATE DATABASE mydatabase DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

Para cambiar el juego de caracteres de una base de datos existente:

ALTER DATABASE mydatabase CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

### Configuraciones recomendadas de la tabla

CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci, email VARCHAR(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

### Cambiando el conjunto de caracteres de las tablas existentes

ALTER TABLE users CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

### Diferencia entre `utf8mb4_general_ci` y `utf8mb4_unicode_ci`

Collation

Características

Casos de uso

utf8mb4_general_ci

La comparación es rápida pero menos precisa

Sistemas orientados al rendimiento

utf8mb4_unicode_ci

Cumple con el estándar Unicode, lo que permite comparaciones más precisas.

Uso general (recomendado)

✅ **Si se necesita soporte multilingüe o un ordenamiento preciso, seleccione `utf8mb4_unicode_ci`**. ### Optimización de índices

CREATE FULLTEXT INDEX idx_fulltext ON articles(content);

### Resumen

* **Se recomienda la combinación de `utf8mb4` + `utf8mb4_unicode_ci`**
* **Estandarice la configuración del servidor (`my.cnf`) y unifique el conjunto de caracteres en la conexión**
* **Especifique explícitamente `utf8mb4` a nivel de base de datos, tabla y columna**
* **El uso de `VARCHAR(191)` evita limitaciones de longitud de índice**
* **El uso de `utf8mb4_unicode_ci` permite comparaciones precisas**

## 8. Preguntas Frecuentes (FAQ)

Hemos compilado preguntas comunes sobre el cambio de conjuntos de caracteres MySQL en operaciones del mundo real.  
**Cómo manejar errores y elegir configuraciones óptimas** se explica en detalle.

### ¿Cuál es la diferencia entre `utf8` y `utf8mb4`?

SHOW VARIABLES LIKE ‘character_set_server’;

### ¿Se perderán datos al cambiar el conjunto de caracteres MySQL?

mysqldump -u root -p –default-character-set=utf8mb4 mydatabase > backup.sql

### ¿Cómo resolver caracteres confusos?

UPDATE users SET = CONVERT(CAST(CONVERT(name USING latin1) AS BINARY) USING utf8mb4);

### ¿Cuáles son los riesgos de convertir de `latin1` a `utf8mb4`?

ALTER DATABASE mydatabase CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

### ¿El cambio a `utf8mb4` afecta el rendimiento?

ALTER TABLE users MODIFY COLUMN email VARCHAR(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

### ¿Cuál se debe usar: `utf8mb4_general_ci` o `utf8mb4_unicode_ci`?

Collation

Características

Casos de uso

utf8mb4_general_ci

La comparación es rápida pero carece de precisión

Sistemas orientados al rendimiento

utf8mb4_unicode_ci

Comparación precisa basada en el estándar Unicode

Uso general (recomendado)

### ¿Las consultas se volverán más lentas después de cambiar a `utf8mb4`?

CREATE FULLTEXT INDEX idx_fulltext ON articles(content); «`

Resumen

Recomendamos usar utf8mb4. utf8 no se recomienda debido a sus limitaciones.
Antes de cambiar el conjunto de caracteres, verifique siempre la configuración con SHOW VARIABLES.
Use exportación/importación de datos para evitar caracteres confusos.
Considere el impacto en los índices y recomiende VARCHAR(191).
Tenga en cuenta el rendimiento y configure índices apropiados.

Finalmente

Cambiar los conjuntos de caracteres MySQL no es solo un ajuste de configuración; es una tarea crítica que afecta la integridad de los datos y el rendimiento.
Siguiendo configuraciones y procedimientos adecuados, puede migrar a utf8mb4 de manera segura y efectiva.

🔹 ¡Siga los pasos de este artículo para aplicar la configuración adecuada del conjunto de caracteres! 🔹