Character Set
Un character set (conjunto de caracteres) define qué caracteres puede almacenar MySQL y cuántos bytes usa para cada uno. Determina la correspondencia entre bytes almacenados y los caracteres que representan. MySQL soporta más de 40 character sets, pero en la práctica utf8mb4 es el estándar recomendado porque soporta todos los caracteres Unicode, incluidos emojis.
Ver character sets disponibles
SHOW CHARACTER SET;MySQL muestra todos los character sets soportados. Los más relevantes:
| Charset | Descripción | Bytes/char | Collation por defecto |
|---|---|---|---|
| utf8mb4 | UTF-8 Unicode completo | 1-4 | utf8mb4_0900_ai_ci |
| utf8mb3 | UTF-8 (solo BMP, 3 bytes) | 1-3 | utf8mb3_general_ci |
| latin1 | ISO 8859-1 Western European | 1 | latin1_swedish_ci |
| ascii | US ASCII | 1 | ascii_general_ci |
| binary | Binario puro | 1 | binary |
utf8mb3 (antes llamado utf8) solo soporta caracteres del Basic Multilingual Plane (hasta 3 bytes). No puede almacenar emojis ni algunos caracteres CJK. Desde MySQL 8.0, utf8mb4 es el character set por defecto.
Niveles de configuración
MySQL permite configurar el character set en cuatro niveles, de más general a más específico:
Nivel de servidor
-- Ver el character set del servidor
SHOW VARIABLES LIKE 'character_set_server';| Variable_name | Value |
|---|---|
| character_set_server | utf8mb4 |
-- Ver la collation del servidor
SHOW VARIABLES LIKE 'collation_server';| Variable_name | Value |
|---|---|
| collation_server | utf8mb4_0900_ai_ci |
El character set del servidor se configura en el archivo my.cnf o my.ini:
-- En el archivo de configuración:
-- [mysqld]
-- character-set-server=utf8mb4
-- collation-server=utf8mb4_0900_ai_ciNivel de base de datos
Cada base de datos puede tener su propio character set. Si no se especifica, hereda el del servidor:
CREATE DATABASE mi_db CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;-- Ver el character set de una base de datos
SELECT DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME
FROM information_schema.SCHEMATA
WHERE SCHEMA_NAME = 'tienda_mysql';| DEFAULT_CHARACTER_SET_NAME | DEFAULT_COLLATION_NAME |
|---|---|
| utf8mb4 | utf8mb4_0900_ai_ci |
-- Cambiar el character set de una base de datos existente
ALTER DATABASE mi_db CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;Cambiar el character set de una base de datos solo afecta a las tablas que se creen después del cambio. Las tablas existentes mantienen su character set original.
Nivel de tabla
CREATE TABLE mi_tabla (
id INT PRIMARY KEY,
nombre VARCHAR(100)
) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;-- Ver character set de las tablas de tienda_mysql
SELECT TABLE_NAME, TABLE_COLLATION
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'tienda_mysql'
ORDER BY TABLE_NAME;| TABLE_NAME | TABLE_COLLATION |
|---|---|
| categorias | utf8mb4_0900_ai_ci |
| clientes | utf8mb4_0900_ai_ci |
| detalle_pedidos | utf8mb4_0900_ai_ci |
| empleados | utf8mb4_0900_ai_ci |
| etiquetas_producto | utf8mb4_0900_ai_ci |
| pedidos | utf8mb4_0900_ai_ci |
| productos | utf8mb4_0900_ai_ci |
| resenas | utf8mb4_0900_ai_ci |
Nivel de columna
Puedes especificar un character set diferente para columnas individuales:
CREATE TABLE multi_charset (
id INT PRIMARY KEY,
nombre VARCHAR(100) CHARACTER SET utf8mb4,
codigo VARCHAR(20) CHARACTER SET ascii,
descripcion TEXT CHARACTER SET utf8mb4
);Usar ascii para columnas que solo contendrán caracteres ASCII (como códigos, identificadores) ahorra espacio porque cada carácter ocupa exactamente 1 byte.
Herencia de character set
Si no especificas un character set, se hereda del nivel superior:
| Nivel | Hereda de |
|---|---|
| Columna | Tabla |
| Tabla | Base de datos |
| Base de datos | Servidor |
utf8mb4 vs utf8mb3
utf8mb3 fue el character set utf8 original de MySQL. Solo soportaba hasta 3 bytes por carácter, lo que excluye muchos caracteres Unicode modernos:
-- Crear tabla con utf8mb3
CREATE TABLE test_charset (
texto_mb3 VARCHAR(100) CHARACTER SET utf8mb3,
texto_mb4 VARCHAR(100) CHARACTER SET utf8mb4
);
-- Insertar emoji: falla en utf8mb3
-- INSERT INTO test_charset (texto_mb3) VALUES ('Hola 😀');
-- Error: Incorrect string value
-- Funciona en utf8mb4
INSERT INTO test_charset (texto_mb4) VALUES ('Hola 😀');
SELECT texto_mb4, LENGTH(texto_mb4) AS bytes, CHAR_LENGTH(texto_mb4) AS chars
FROM test_charset;| texto_mb4 | bytes | chars |
|---|---|---|
| Hola 😀 | 9 | 6 |
El emoji ocupa 4 bytes. LENGTH cuenta bytes, CHAR_LENGTH cuenta caracteres. Con utf8mb4, ambas funciones devuelven valores diferentes para textos con caracteres multibyte.
| Característica | utf8mb3 | utf8mb4 |
|---|---|---|
| Bytes por carácter | 1-3 | 1-4 |
| Emojis | No | Sí |
| Unicode completo | No (solo BMP) | Sí |
| Estado | Obsoleto | Recomendado |
| Alias en MySQL 8.0 | utf8 (deprecated) | - |
Character set de la conexión
MySQL usa tres variables para la conexión cliente-servidor:
SHOW VARIABLES LIKE 'character_set_%';| Variable_name | Value |
|---|---|
| character_set_client | utf8mb4 |
| character_set_connection | utf8mb4 |
| character_set_database | utf8mb4 |
| character_set_results | utf8mb4 |
| character_set_server | utf8mb4 |
| character_set_system | utf8mb3 |
character_set_client: character set del texto que envía el clientecharacter_set_connection: character set usado para procesar las consultascharacter_set_results: character set del texto que devuelve el servidor
Para configurar los tres a la vez:
SET NAMES utf8mb4;
-- Equivale a:
-- SET character_set_client = utf8mb4;
-- SET character_set_connection = utf8mb4;
-- SET character_set_results = utf8mb4;Funciones de character set
-- Ver el character set de un string
SELECT CHARSET('Hola') AS charset_texto;| charset_texto |
|---|
| utf8mb4 |
-- Convertir entre character sets
SELECT CONVERT('Hola' USING latin1) AS convertido;
-- Ver el character set resultante
SELECT CHARSET(CONVERT('Hola' USING latin1)) AS charset_convertido;| charset_convertido |
|---|
| latin1 |
-- HEX muestra la representación en bytes
SELECT
HEX('A') AS ascii_char,
HEX('ñ') AS latin_char,
HEX('€') AS euro_char,
HEX('😀') AS emoji_char;| ascii_char | latin_char | euro_char | emoji_char |
|---|---|---|---|
| 41 | C3B1 | E282AC | F09F9880 |
A ocupa 1 byte, ñ ocupa 2 bytes, € ocupa 3 bytes y el emoji ocupa 4 bytes en UTF-8.
Verificar character set de columnas
SELECT COLUMN_NAME, CHARACTER_SET_NAME, COLLATION_NAME
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = 'tienda_mysql'
AND TABLE_NAME = 'productos'
AND CHARACTER_SET_NAME IS NOT NULL;| COLUMN_NAME | CHARACTER_SET_NAME | COLLATION_NAME |
|---|---|---|
| nombre | utf8mb4 | utf8mb4_0900_ai_ci |
| descripcion | utf8mb4 | utf8mb4_0900_ai_ci |
Solo las columnas de tipo cadena tienen character set. Las columnas numéricas, temporales y binarias no lo necesitan.
Recomendaciones
-
Usa
utf8mb4siempre. Es el character set por defecto en MySQL 8.0 y soporta todos los caracteres Unicode. -
Asegúrate de que la conexión use
utf8mb4. ConfiguraSET NAMES utf8mb4o usa el parámetro de conexión en tu driver. -
Usa
asciipara columnas que solo necesiten caracteres ASCII (códigos de país, moneda, identificadores). Ahorra espacio. -
No uses
utf8mb3/utf8. Está obsoleto y no soporta emojis ni muchos caracteres Unicode.
Limpieza
DROP TABLE IF EXISTS test_charset;
DROP TABLE IF EXISTS multi_charset;
DROP DATABASE IF EXISTS mi_db;En el siguiente artículo veremos las collations, que determinan cómo se comparan y ordenan los caracteres dentro de un character set.
Escrito por Eduardo Lázaro
