Consultas de textos case sensitive en Mysql

Mysql es por defecto case insensitive (no sensible a las mayúsculas): no diferencia las mayúsculas de las minúsculas. Esto se debe a que tiene configurado inicialmente el collation ‘latin1_swedish_ci’.

mysql> SELECT nombre_usuario FROM usuarios WHERE nombre_usuario LIKE 'al%'; # retorna usuarios con nombres como 'Alberto', 'Álvaro', 'alejo'

Por lo general, cuando hacemos una comparación es muy conveniente este comportamiento dado que no importa la capitalización que usemos, encontraremos los resultados.

 

Tengamos en cuenta que para los campos con caracteres no binarios: CHAR, VARCHAR y TEXT, la comparación depende del collation de los mismos.

En cambio, para los campos binarios: BINARY, VARBINARY y BLOB se utiliza el valor numérico de los bytes en la comparación, por lo que serán case sensitive en el caso de los caracteres.

Si se compara una cadena binaria y una no-binaria, la comparación se realiza como si fueran ambas binarias.

 

Pero en ciertos casos, cuando deseamos comparar los caracteres contemplando su capitalización, podemos optar por alguna de las siguientes alternativas:

  • Usar el operador COLLATE para indicar un collation que sea case sensitive (termina con _cs o _bin)  que pertenezca al juego de caracteres correspondiente a un campo, un valor o a ciertas partes de la consulta.
    • Disponible a partir de Mysql 4.1
  • Usar el operador BINARY sobre el valor o columna en la consulta
  • Cambiar  el collation de la columna CHAR(N), VARCHAR(N) o TEXT mediante un ALTER TABLE por uno que sea case sensitive:
    • agregando BINARY al final, lo cual especifica el collation _bin para el juego de caracteres correspondiente
    • indicando el CHARSET y COLLATION específicos
  • Cambiar el tipo de dato de la columna mediante un ALTER TABLE por uno que sea case sensitive:
    • BINARY, VARBINARY o BLOB

Ejemplos de uso de COLLATE

mysql> SELECT nombre_usuario FROM usuarios WHERE nombre_usuario LIKE 'Al%' COLLATE latin1_spanish_cs; # retorna usuarios con nombres como 'Alberto' o 'Álvaro'. NO 'alejo'

mysql> SELECT nombre_usuario FROM usuarios WHERE nombre_usuario COLLATE latin1_bin LIKE 'al%'; # retorna usuarios con nombres como 'alejo'. NO 'Alberto' ni 'Álvaro'

 

Sabiendo también cómo cambiar el tipo de dato a un valor o a un campo, podemos notar que todas las expresiones son equivalentes cuando se utilizan en una comparación:

CAST(nombre AS BINARY) = CONVERT(nombre,BINARY) = BINARY nombre = nombre COLLATE latin1_bin

COLLATE no cambia el tipo de dato, solo aplica un collation al momento de usar el campo en una comparación

Tagged with: , ,
Publicado en Aplicaciones