Collation

Una collation define las reglas para comparar y ordenar caracteres dentro de un character set. Determina si 'a' y 'A' son iguales, si 'ñ' va después de 'n' o después de 'o', y si 'café' y 'cafe' coinciden en una búsqueda. Cada character set tiene una collation por defecto, pero puede tener varias disponibles.

Convenciones de nombres

Las collations siguen un patrón que indica su comportamiento:

charset_idioma_modificadores

Los sufijos indican la sensibilidad:

SufijoSignificadoEjemplo
_aiAccent Insensitive'café' = 'cafe'
_asAccent Sensitive'café' ≠ 'cafe'
_ciCase Insensitive'abc' = 'ABC'
_csCase Sensitive'abc' ≠ 'ABC'
_binBinarioCompara byte a byte
_ksKana SensitiveDistingue hiragana/katakana

Ejemplos de collations comunes:

CollationDescripción
utf8mb4_0900_ai_ciUnicode 9.0, case/accent insensitive (defecto MySQL 8.0)
utf8mb4_0900_as_csUnicode 9.0, case/accent sensitive
utf8mb4_general_ciGeneral, case insensitive (más rápida, menos precisa)
utf8mb4_binBinaria, compara bytes
utf8mb4_spanish_ciReglas de ordenamiento español

Ver collations disponibles

-- Todas las collations para utf8mb4
SHOW COLLATION WHERE Charset = 'utf8mb4';

Hay muchas. Para ver solo las más usadas:

SELECT COLLATION_NAME, IS_DEFAULT
FROM information_schema.COLLATIONS
WHERE CHARACTER_SET_NAME = 'utf8mb4'
  AND COLLATION_NAME LIKE '%0900%'
ORDER BY COLLATION_NAME
LIMIT 10;
COLLATION_NAMEIS_DEFAULT
utf8mb4_0900_ai_ciYes
utf8mb4_0900_as_ci
utf8mb4_0900_as_cs
utf8mb4_0900_bin

utf8mb4_0900_ai_ci es la collation por defecto de MySQL 8.0. El 0900 hace referencia a Unicode 9.0.

Efecto en comparaciones

La collation afecta directamente cómo funcionan WHERE, ORDER BY, DISTINCT y los índices:

CREATE TABLE test_collation (
    texto VARCHAR(100) COLLATE utf8mb4_0900_ai_ci
);
 
INSERT INTO test_collation VALUES ('café'), ('Cafe'), ('CAFÉ'), ('cafe');
 
-- Con collation ai_ci (accent insensitive, case insensitive)
SELECT texto FROM test_collation WHERE texto = 'cafe';
texto
café
Cafe
CAFÉ
cafe

Las cuatro filas coinciden porque la collation ai_ci ignora mayúsculas y acentos.

-- Comparar con collation as_cs (accent sensitive, case sensitive)
SELECT texto FROM test_collation WHERE texto = 'cafe' COLLATE utf8mb4_0900_as_cs;
texto
cafe

Solo coincide la escritura exacta.

Efecto en ordenamiento

CREATE TABLE test_orden (
    nombre VARCHAR(100) COLLATE utf8mb4_0900_ai_ci
);
 
INSERT INTO test_orden VALUES ('ñandú'), ('naranja'), ('oliva'), ('nuez');
 
-- Ordenamiento con collation por defecto
SELECT nombre FROM test_orden ORDER BY nombre;
nombre
naranja
nuez
ñandú
oliva

Con utf8mb4_0900_ai_ci, la ñ se ordena correctamente entre la n y la o, siguiendo las reglas Unicode.

-- Comparar con collation binaria
SELECT nombre FROM test_orden ORDER BY nombre COLLATE utf8mb4_bin;
nombre
naranja
nuez
oliva
ñandú

Con la collation binaria, ñ va al final porque su valor en bytes (0xC3B1) es mayor que el de o (0x6F).

Collation español

MySQL incluye una collation específica para español:

CREATE TABLE test_espanol (
    palabra VARCHAR(100)
);
 
INSERT INTO test_espanol VALUES ('carro'), ('casa'), ('chico'), ('cielo');
 
-- Con collation general
SELECT palabra FROM test_espanol ORDER BY palabra COLLATE utf8mb4_0900_ai_ci;
palabra
carro
casa
chico
cielo
-- Con collation española tradicional
SELECT palabra FROM test_espanol ORDER BY palabra COLLATE utf8mb4_es_trad_0900_ai_ci;
palabra
carro
casa
cielo
chico

La collation utf8mb4_es_trad_0900_ai_ci (español tradicional) trata ch como una letra separada que va después de c. La collation estándar la trata como c + h.

CollationTratamiento de chTratamiento de ll
utf8mb4_0900_ai_cic + h (estándar)l + l (estándar)
utf8mb4_es_trad_0900_ai_ciLetra ch (después de c)Letra ll (después de l)
utf8mb4_spanish_cic + h (estándar)l + l (estándar)

En la práctica, la mayoría de las aplicaciones en español usan utf8mb4_0900_ai_ci (la collation por defecto), que sigue las reglas de la RAE modernas donde ch y ll no son letras separadas.

Collation en tienda_mysql

SELECT TABLE_NAME, TABLE_COLLATION
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'tienda_mysql';
TABLE_NAMETABLE_COLLATION
categoriasutf8mb4_0900_ai_ci
clientesutf8mb4_0900_ai_ci
detalle_pedidosutf8mb4_0900_ai_ci
empleadosutf8mb4_0900_ai_ci
etiquetas_productoutf8mb4_0900_ai_ci
pedidosutf8mb4_0900_ai_ci
productosutf8mb4_0900_ai_ci
resenasutf8mb4_0900_ai_ci

Todas usan la collation por defecto, lo que significa que las búsquedas en texto son case-insensitive y accent-insensitive:

-- Buscar "maria" encuentra "María"
SELECT nombre, apellidos FROM clientes WHERE nombre = 'maria';
nombreapellidos
MaríaGarcía López
-- Buscar sin acento encuentra con acento
SELECT nombre FROM productos WHERE nombre LIKE '%electronica%';

Esta consulta no devuelve resultados porque LIKE con la collation ai_ci no ignora acentos dentro de LIKE en todas las versiones. Para búsquedas insensibles a acentos, es mejor usar la collation explícitamente o normalizar los datos.

COLLATE en consultas

Puedes usar COLLATE en cualquier expresión para cambiar la collation temporalmente:

-- Búsqueda case-sensitive
SELECT nombre, precio
FROM productos
WHERE nombre COLLATE utf8mb4_0900_as_cs = 'iphone 15 pro';

Esta consulta no devuelve resultados porque el nombre real es iPhone 15 Pro (con mayúsculas).

-- Búsqueda case-sensitive correcta
SELECT nombre, precio
FROM productos
WHERE nombre COLLATE utf8mb4_0900_as_cs = 'iPhone 15 Pro';
nombreprecio
iPhone 15 Pro1299.99

Cambiar collation de una columna

ALTER TABLE mi_tabla
MODIFY nombre VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_as_cs;

Cambiar la collation de una columna con datos existentes puede ser una operación costosa en tablas grandes, ya que MySQL debe reconstruir los índices.

Collation y UNIQUE

La collation afecta las restricciones UNIQUE. Con ai_ci, valores que difieren solo en mayúsculas o acentos se consideran duplicados:

CREATE TABLE test_unique (
    email VARCHAR(100) UNIQUE COLLATE utf8mb4_0900_ai_ci
);
 
INSERT INTO test_unique VALUES ('user@email.com');
 
-- Esto falla: duplicado por collation ci
-- INSERT INTO test_unique VALUES ('User@Email.com');
-- Error: Duplicate entry

Esto es generalmente el comportamiento deseado para emails, pero si necesitas distinguir mayúsculas:

CREATE TABLE test_unique_cs (
    codigo VARCHAR(50) UNIQUE COLLATE utf8mb4_0900_as_cs
);
 
INSERT INTO test_unique_cs VALUES ('abc');
INSERT INTO test_unique_cs VALUES ('ABC');
 
SELECT * FROM test_unique_cs;
codigo
abc
ABC

Con collation as_cs, 'abc' y 'ABC' son valores diferentes y ambos se aceptan.

Collation y ORDER BY

SELECT nombre, precio
FROM productos
WHERE categoria_id = 6
ORDER BY nombre COLLATE utf8mb4_0900_ai_ci;
nombreprecio
Google Pixel 8699.00
iPhone 15 Pro1299.99
Samsung Galaxy S24899.99
Xiaomi 14599.99
-- Ordenamiento binario (por valor de bytes)
SELECT nombre, precio
FROM productos
WHERE categoria_id = 6
ORDER BY nombre COLLATE utf8mb4_bin;
nombreprecio
Google Pixel 8699.00
Samsung Galaxy S24899.99
Xiaomi 14599.99
iPhone 15 Pro1299.99

Con collation binaria, iPhone va al final porque la i minúscula (0x69) tiene un valor mayor que las mayúsculas G (0x47), S (0x53) y X (0x58).

Recomendaciones

Caso de usoCollation recomendada
General (por defecto)utf8mb4_0900_ai_ci
Contraseñas, tokensutf8mb4_bin
Nombres de usuario (case-sensitive)utf8mb4_0900_as_cs
Emails (case-insensitive)utf8mb4_0900_ai_ci
Español con ch/ll tradicionalutf8mb4_es_trad_0900_ai_ci
Comparaciones exactasutf8mb4_0900_as_cs o utf8mb4_bin

Limpieza

DROP TABLE IF EXISTS test_collation;
DROP TABLE IF EXISTS test_orden;
DROP TABLE IF EXISTS test_espanol;
DROP TABLE IF EXISTS test_unique;
DROP TABLE IF EXISTS test_unique_cs;

Con esto completamos la sección de conjuntos de caracteres. En la siguiente sección exploraremos los índices en MySQL, una herramienta fundamental para optimizar el rendimiento de las consultas.

Escrito por Eduardo Lázaro