¿Alguna vez has pensado en almacenar emojis en tu Base de datos?, Si, emojis, de tal forma que tus usuarios puedan expresar sus ideas de una forma distinta 😎. En códigofacilito con nuestra nueva actualización esto ya es posible. Dentro de los comentarios tú ya puedes utilizar este tipo de "imágenes" sin ningún problema. El trabajo que se necesito para que esto fuera posible no es mucho, de hecho, solo necesitamos ejecutar un par de sentencias y modificar un archivo en concreto.
En este post aprenderemos a almacenar emojis en nuestra Base de datos. Lo interesante aquí, es el por que de los cambios. Al desarrollar este pequeño feature, me percate de ciertas cosas que estaba dando por hecho. Concretamente en la codificación de lo strings. De forma personal solía pensar que utilizando utf-8 con MySQL podría dar solución a todos mis problemas de escritura, pero cómo veremos más adelante eso no es así.
El título original de este post iba a ser: De UTF-8 a utf8mb4 con MySQL, pero rápidamente fue descartado por no tener la palabra emoji en el 🐊 .
UTF-8
Antes de entrar de lleno con el tema de almacenamiento de emojis debemos dejar en claro un par de cosas, la primera es que la codificación utf-8 nos permite representar cualquier símbolo dentro del listado Unicode. prácticamente podemos utilizar 1,114,112 símbolos. Si, son muchísimos, esto incluyes a los emojis.
Otra cosa a tomar en cuenta es que con utf-8 nosotros podemos utilizar hasta 4 bytes para representar un carácter, y adivina, 4 bytes es lo necesario para representar un emoji 😲 .
UTF8 en MySQL
En MySQL nosotros podemos definir que tipo de codificación queremos utilizar en : Una base de datos, una tabla e inclusive en una columna, así de especificamos podemos llegar a ser.
Entre el tipo de codificación que podemos utilizar se encuentra utf-8.
Veamos unos ejemplos :
CREATE DATABASE mi_base_de_datos
CHARACTER SET utf8 COLLATE utf8_general_ci;
CREATE TABLE mi_tabla (titulo VARCHAR(50))
CHARACTER SET utf8 COLLATE utf8_general_ci;
ALTER TABLE mi_tabla ADD COLUMN columna VARCHAR(50)
CHARACTER SET utf8 COLLATE utf8_general_ci;
Bien, con todos estos conocimientos, uno pensaría que es posible insertar un emoji en una columna que acepte utf-8, por ejemplo.
INSERT INTO mi_tabla VALUES (' 🦕 ');
Sin embargo, si ejecutamos esta sentencias vamos a tener un error 😓.
ERROR 1366 (HY000): Incorrect string value: '\xF0\x9F\xA6\x95' for column
Esto se debe a que en MySQL el utf-8 que utilizamos no es el verdadero utf-8 😳.
¿A qué me refiero con esto? Bueno, Con MySQL utilizando utf_8 únicamente podremos representar un carácter hasta con 3 bytes, lo cual no está nada mal para cuestiones idiomáticas, sin embargo, estamos limitados en almacenar otros tipos de símbolos, por ejemplo los emojis 🤔.
En lo personal yo desconocía este comportamiento, no fue hasta que intente almacenar un emoji que me lleve esta sorpresa 🐽.
Entonces, ¿Podemos o no almacenar emojis en MySQL?, la respuesta es si, pero no utilizando el "utf-8" que nos provee.
En 2010 (Con su versión 5.5.3)MySQL agrega una variante a utf-8 llamada utf8mb4. Con este nuevo tipo de codificación, cada carácter puede ser representado hasta 4 bytes, es decir, ahora si, un verdadero utf-8.
Entonces, si queremos representar verdaderamente el utf-8 y no únicamente de forma parcial, debemos de utilizar utf8mb4.
CREATE DATABASE mi_base_de_datos
CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
CREATE TABLE mi_tabla (titulo VARCHAR(50))
CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
ALTER TABLE mi_tabla ADD COLUMN columna VARCHAR(50)
CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
Listo, de esta forma nuestra base de datos, nuestra tabla o nuestra columna podrá almacenar cualquier tipo de símbolo.
Si queremos cerciorarnos que todo este funcionando correctamente podemos volver a intentar insertar.
SET NAMES utf8mb4;
INSERT INTO mi_tabla VALUES (' 🦕 ');
y con esto vamos a obtener nuestro maravilloso mensaje
Query OK, 1 row affected (0.00 sec)
Con SET NAMES indicamos que durante toda la sesión estaremos utilizando utf8mb4.
Proyecto en producción. De utf-8 a utf8mb4
Los comando que vimos hace un par de minutos los estaremos utilizando cuando no tengamos datos en nuestra base de datos, tabla o columna, sin embargo, ¿Qué pasa cuando nuestro proyecto ya está en producción o ya posee una cantidad de datos significativa? En esos caso nosotros debemos de hacer un par de modificaciones.
Antes de hacer las modificaciones, recomiendo lo siguiente:
- Hacer un respaldo de nuestra base de datos. No nos hagamos los valientes, algo puede salir mal.
- Actualizar el servidor (MySQL). Siempre es bueno estar actualizado.
Las sentencias quedarían de la siguiente manera.
ALTER DATABASE mi_base_de_datos
CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
ALTER TABLE mi_tabla
CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE mi_tabla CHANGE columna columna VARCHAR(191)
CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
Una vez ejecutada la sentencia, o sentencias, debemos de reparar y optimizar nuestras tablas. Esto para evitar cualquier tipo de error que haya ocurrido.
REPAIR TABLE mi_tabla;
OPTIMIZE TABLE mi_tabla;
Dentro de nuestro proyecto deberíamos modificar el archivo config que utilizamos para realizar la conexión a nuestra base de datos. En Ruby on Rails sería el archivo database.yml.
Pudiera quedar de la siguiente manera :
production:
adapter: mysql2
database: db
username: username
password: passwod
host: direccion_ip
port: 3306
timeout: 5000
pool: 25
encoding: utf8mb4
Conclusión
Mi conclusión es muy sencilla. No utilicemos utf-8, en lugar de ello obtenemos por utf8mb4🍻.