Character set y Collate de una base de datos mysql/mariadb

Published on

in

, ,

Corría el año 2014, el mes de Noviembre, para ser exactos. Yo me encontraba haciendo cambios en un sistema que generaba reportes en PDF utilizando Jasper Reports. Los datos que se debían plasmar en la plantilla para los documentos se obtenían de una base de datos montada en MySQL.

Conviene recordar en este punto, que quien suscribe viene de los años en que MySQL no existía, lo más parecido que yo conocí en mis primeros años de informática era un programa llamado dBase IV. Si estás familiarizado con MS Access (con sus debidas diferencias) era muy similar pero con interfaz de texto. Te permitía crear formularios para capturar, consultar, actualizar y eliminar datos. Podías buscar datos por llave primaria, descripciones, etc. Una base de datos.

Desconozco si soportaba SQL; la verdad es que lo conocí en un curso de informática a una temprana edad en la que no entendía realmente l que estaba haciendo y solo mecanicé, y probablemente quien impartía el curso no tenía muy claro tampoco qué estaba haciendo o no le daba la seriedad debida.

Estamos hablando de los años en que Windows 3.1 era la norma. Además del sistema operativo y su suite de oficina, casi no había otros programas con interfaz en español (u otro idioma que no fuera Inglés), y dBase no era la excepción. Toda su consola estaba en Inglés y derivado los ejercicios que hice en él, también su motor de almacenamiento. No permitía guardar vocales acentuadas, con diéresis o eñes.

Cuando por fin tuve acceso a MySQL, fue todo un cambio de paradigma. SQL Server era (es) demasiado caro para proyectos personales o de escuela, no digamos ya otras marcas (IBM, Oracle, Progress). MS Access estaba bien para soluciones pequeñas pero era complicado generar una solución cliente-servidor con una base de datos centralizada. Todo eso cambió con MySQL.

Otra gran ventaja que encontré es que MySQL ya daba facilidades para trabajar datos (texto) en Español y otros idiomas. Fue un paso de escala de grises a una paleta de colores antes fuera del alcance el estudiante promedio de los años 2000.

Lo que desconocía por no haberme documentado lo suficiente era el concepto de Collate. Y justo ahí es donde regresamos a 2014. Para obtener un dato que necesitaba en el PDF tenía que validar algún particular en la base de datos comparando textos, si el dato existía, lo obtendría y lo plasmaría en el PDF, si no, se quedaría en blanco.

Habiendo hecho la programación correspondiente, ejecuto mis pruebas unitarias y mientras van corriendo eventualmente llego a un error:

La base de datos devolvió más de un registro cuando esperaba solo uno.

Cuando reviso e identifico qué registro generó el error, hago el select en turno y cuál es mi sorpresa:

Select * from tabla where campo_tal = "Esta cadena"
(Dramatización: no recuerdo el select pero sí que la condición era cumplir con una cadena de texto con letras mayúsculas y minúsculas)

Nada complejo respecto al select, sólo hay que enfatizar que la condición implicaba encontrar un texto que incluía letras mayúsculas y minúsculas. Mi sorpresa fue al recibir los resultados:

Esta cadena
esta cadena
esta Cadena

Estuve revisando el código, el select, el motor de PDFs, dándole vueltas al tema hasta que luego de cierto tiempo de intentar arreglarlo me convencí de que había un error. Así que consulté con mi colega y le dije:

-Mira, este select me está trayendo cadenas que no coinciden, yo la pido con letras mayúsculas y me está trayendo las que encuentra. Sí es el mismo texto pero no coinciden las condiciones.

Y la respuesta de mi colega fue:

-Creo que hay una forma de configurar MySQL para indicarle que no sea sensible a mayúsculas y minúsculas…

Esa forma de configurar MySQL es precisamente el collate, que define el conjunto de reglas con el que se compararán conjuntos de caracteres (cadenas), para definir igualdad, orden, etc.

Al crear una base de datos o tabla, llevarás siempre un character set y un collate. Si no los defines explícitamente en la instrucción, se usarán los dados por omisión en tu instalación.

Piensa qué tipo de datos almacenarás y cómo trabajarás con ellos. Por ejemplo, si para tu necesidad, letras mayúsculas y minúsculas son indistintas, elige un collate CASE INSENSITIVE, eso evitará que cada que tengas que comparar cadenas tengas que hacer un UPPERCASE.

El siguiente es un ejemplo de la creación de base de datos usando utf8 como su conjunto de caracteres (almacenará los textos usando el estándar utf8) y para collate usará el mismo utf8 de forma general y el sufijo «_ci» nos indica que es «CASE INSENSITIVE».

CREATE DATABASE mydatabase CHARACTER SET utf8 COLLATE utf8_general_ci;

Esta decisión aunque parece trivial, no lo es. Quizás podrías ir por una definición general, como es la que dejo en el párrafo anterior, esa es la configuración que mejor me ha funcionado en mis soluciones ya que he tenido que almacenar datos que no son necesariamente textos en Inglés o Español, y donde la sensibilidad a letras mayúsculas no es necesaria.

Para más información por favor consulta la documentación oficial, es muy interesante.

https://dev.mysql.com/doc/refman/8.0/en/charset-general.html

Deja un comentario

Descubre más desde Crónicas de Programación

Suscríbete ahora para seguir leyendo y obtener acceso al archivo completo.

Seguir leyendo