notifications Notificaciones

Marcar todas como leídas

Ver más

lightbulb_outline

2726 veces ha sido leído este artículo

Emojis en tu aplicación. Deja de utilizar utf8 con MySQL.

Lo lees en 4 Min.

¿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. 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 a 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🍻.

Recomendaciones

Redux - No sabes que lo necesitas hasta que lo usas

Lo lees en 6 Min.

Redux es una de esas tecnologías enigmáticas, todo el mundo habla de ella, la usa, pero quienes a...

 

Ejercicios de Diagrama de flujo

Lo lees en 1 Min.

¡Hola de nuevo! Muchísimas gracias por seguir y estar tomando el curso de Algoritmos, este artíc...

 

React Hooks

Lo lees en 4 Min.

Hace unos días, durante la ReactConf, Sophie Alpert quien maneja el equipo de desarrollo de React...

 

Crear pruebas automatizadas en Laravel con phpunit

Lo lees en 2 Min.

Hola developers. En esta ocasión quiero compartir como empezar a utilizar TDD (Test Driver Devel...

 

Comunidad