Cómo almacenar caracteres emoji en la base de datos MySQL

173

Estoy usando el personaje Emoji en mi proyecto. Que los caracteres se guardan (??) en la base de datos mysql. Había utilizado la clasificación predeterminada de la base de datos en utf8mb4_general_ci. Muestra

1366 Valor de cadena incorrecto: '\ xF0 \ x9F \ x98 \ x83 \ xF0 \ x9F ...' para la columna 'comentario' en la fila 1

Selvamani P
fuente
1
¿Cómo está guardando sus datos? ¿Puedes mostrarnos ese código?
Tomas Buteler
1
Gracias por tu comentario. He encontrado una solución para esta colección predeterminada de la base de datos de cambios como ** utf8mb4 ** y también para la colección de la tabla de cambios como ** CHARACTER SET utf8mb4 COLLATE utf8mb4_bin **. ALTER TABLE Tablename CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin
Selvamani P
1
Código: insert into tablename (column1,column2,column3,column4,column5,column6,column7) values ('273','3','Hdhdhdh😜😀😊😃hzhzhzzhjzj 我爱你 ❌',49,1,'2016-09-13 08:02:29','2016-09-13 08:02:29'Establecer utf8mb4 en la conexión de la base de datos: $database_connection = new mysqli($server, $user,$password,$database_name); $database_connection->set_charset("utf8mb4");
Selvamani P

Respuestas:

31

paso 1, cambia el juego de caracteres predeterminado de tu base de datos:

ALTER DATABASE database_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;

paso 2, establece el juego de caracteres al crear la tabla:

CREATE TABLE IF NOT EXISTS table_name (
...
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci;

o alterar la mesa

ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE table_name modify name text charset utf8mb4;
ospider
fuente
Seguí estas consultas y paré y reinicié el servidor mysql, pero cuando trato de insertar emojis en mi tabla sigo teniendo el mismo error. Todos los comandos pasaron exitosamente excepto el INSERT. INSERTAR EN Entradas (fecha, hora, título) VALORES (2018-05-20 ', '12: 38: 00', 'Descripción de la prueba con emoji: 😊❤️'); La configuración de la columna es Clasificación: utf8mb4_0900_ai_ci Definición: texto descriptivo
1
Su conexión también debe ser utf8mb4 no utf8 para que funcione.
Henrik Hansen
3
@ospider, en el paso 2 usas utfmb4_general_ci en lugar de unicode, ¿alguna razón?
Warren
265

1) Base de datos: cambie la clasificación predeterminada de la base de datos como utf8mb4.

2) Tabla: Cambiar la clasificación de la tabla como CHARACTER SET utf8mb4 COLLATE utf8mb4_bin.

Consulta:

ALTER TABLE Tablename CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin

3) Código:

INSERT INTO tablename (column1, column2, column3, column4, column5, column6, column7)
VALUES ('273', '3', 'Hdhdhdh😜😀😊😃hzhzhzzhjzj 我爱你 ❌', 49, 1, '2016-09-13 08:02:29', '2016-09-13 08:02:29')

4) Establecer utf8mb4en la conexión de la base de datos:

  $database_connection = new mysqli($server, $user, $password, $database_name); 
  $database_connection->set_charset('utf8mb4');
Selvamani P
fuente
44
¿Es posible sin cambiar la colección predeterminada de la base de datos?
AliN11
23
Esto no está funcionando para mí. Estoy obteniendo "???" en lugar de emoticones. solo "☺" esta sonrisa llegó a la base de datos de forma segura.
Desarrollador curioso
10
Es posible que deba actualizar no solo la tabla a utf8mb4, sino TAMBIÉN las columnas mismas, de lo contrario, ¿pueden aparecer como ?? en lugar de 💙.
Ael
2
Me funcionó, pero no olvides reiniciar MySQL.
Ravi Misra
8
Necesito correr SET NAMES utf8mb4;para comenzar a guardar emoticones; antes de ese comando los estaba salvando como??
cubbuk
18

Tanto las bases de datos como las tablas deben tener juego de caracteres utf8mb4y clasificación utf8mb4_unicode_ci.

Al crear una nueva base de datos , debe usar:

CREATE DATABASE mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

Si tiene una base de datos existente y desea agregar soporte:

ALTER DATABASE database_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;

También debe establecer el conjunto de caracteres y la clasificación correctos para sus tablas:

CREATE TABLE IF NOT EXISTS table_name (
    ...
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci;

o cámbielo si tiene tablas existentes con muchos datos:

ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

Tenga en cuenta que utf8_general_ciya no se recomienda la mejor práctica. Vea las preguntas y respuestas relacionadas:

¿Cuál es la diferencia entre utf8_general_ci y utf8_unicode_ci en Stack Overflow?

samawaat
fuente
Tengo una base de datos y una tabla que contiene datos. Y cuando ejecuto la segunda instrucción alter, dice que: ERROR 1833 (HY000): No se puede cambiar la columna 'id': se usa en una restricción de clave externa 'FK12njtf8e0jmyb45lqfpt6ad89' de la tabla 'lizbazi.post'
Seyyed Mahdiyar Zerehpoush
@SeyyedMahdiyarZerehpoush: puede salirse con la suya limitando su actualización a columnas específicas que lo requieran, como se describe aquí: stackoverflow.com/a/15781925/1247581 egALTER TABLE mytable MODIFY my_emoji_friendly_text_column VARCHAR(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
theartofrain
alguna diferencia al usar utf8mb4_binvs utf8mb4_unicode_cipara las columnas?
Muhammad Omer Aslam
14

Si está utilizando Solr + Mysql + Java, puede usar:

Esto se puede usar:

  • case1: Cuando no quieres alterar DB.
  • case2: cuando tienes que importar emoticones desde tu Mysql al núcleo de Solr.

En el caso anterior, esta es una de las soluciones para almacenar sus emoticones en su sistema.

Pasos para usarlo:

Biblioteca utilizada: import java.net.URLDecoder; import java.net.URLEncoder;

  1. Use urlEncoder para codificar su String con emoticones.
  2. Almacénelo en DB sin alterar MysqlDB.
  3. Puede almacenarlo en solr core (forma decodificada) si lo desea o puede almacenar forma codificada.
  4. Al recuperar estos emoticones del núcleo de DB o Solr, ahora puede decodificarlos utilizando urlDecoder.

Ejemplo de código:

import java.net.URLDecoder;
import java.net.URLEncoder;

public static void main(String[] args) {
    //SpringApplication.run(ParticipantApplication.class, args);
    System.out.println(encodeStringUrl("🇺🇸🇨🇳🇯🇵🇩🇪🔳🔺🆔🆔🆑3⃣5⃣3⃣‼〽➗➗🎦🔆🎦🔆♋♍♋♍⬅⬆⬅⬅🛂🚹🛂🛄🚳🚬💊🔧💊🗿     "));
    System.out.println(decodeStringUrl("Hello+emoticons%2C%2C%F0%9F%98%80%F0%9F%98%81%F0%9F%98%8A%F0%9F%98%8B%F0%9F%98%8E%F0%9F%98%8A%F0%9F%98%8D%E2%98%BA%F0%9F%98%98%E2%98%BA%F0%9F%98%91%F0%9F%98%87%F0%9F%98%98%F0%9F%98%8B%F0%9F%90%84"));
}

public static String encodeStringUrl(String url) {
    String encodedUrl =null;
    try {
         encodedUrl = URLEncoder.encode(url, "UTF-8");
    } catch (UnsupportedEncodingException e) {
        return encodedUrl;
    }
    return encodedUrl;
}

public static String decodeStringUrl(String encodedUrl) {
    String decodedUrl =null;
    try {
         decodedUrl = URLDecoder.decode(encodedUrl, "UTF-8");
    } catch (UnsupportedEncodingException e) {
        return decodedUrl;
    }
    return decodedUrl;
}
Sunil Gupta
fuente
Gracias por este fragmento de código, que puede proporcionar una ayuda limitada e inmediata. Una explicación adecuada mejoraría en gran medida su valor a largo plazo al mostrar por qué esta es una buena solución al problema y lo haría más útil para futuros lectores con otras preguntas similares. Por favor, editar su respuesta a añadir un poco de explicación, incluyendo los supuestos realizados.
Toby Speight
1
funciona como un encanto, lo usé en el modelo, por lo que realmente no necesito cambiar ninguno de los códigos y la base de datos, solo el modelo de datos en el setter y getter del contenido
bowpunya
1
Las llamadas a funciones de codificación / decodificación tienden a causar problemas. En su lugar, arregle la configuración del juego de caracteres en los distintos lugares.
Rick James
1
Esto no está resolviendo el problema, lo está pasando por alto. Y se encontrará con una serie de problemas con este método, por ejemplo, ralentizará su aplicación porque tiene que decodificar y codificar todo. Además, si ingresa el carácter %, su decodificación se romperá.
Jonathan Laliberte
14

He actualizado mi base de datos y tabla para actualizar de utf8 a utf8mb4 . Pero nada me funciona. Luego intenté actualizar el tipo de datos de columna a blob , por suerte funcionó para mí y los datos se guardaron. Incluso mi base de datos y mi tabla son CHARACTER SET utf8 COLLATE utf8_unicode

Deepak Arora
fuente
13

El comando para modificar la columna es:

ALTER TABLE TABLE_NAME MODIFY COLUMN_NAME TYPE;

Y necesitamos usar type = BLOB

El ejemplo para modificar es el siguiente: -

ALTER TABLE messages MODIFY content BLOB;

Verifiqué que las últimas bases de datos mySQL y otras no necesitan ''usarse en el comando nombre_tabla, nombre_columna, etc.

Recuperar y guardar datos: guarde directamente el contenido del chat en la columna y para recuperar datos, obtenga datos como una matriz de bytes (byte[])de la columna db y luego conviértalos a, stringpor ejemplo, (código Java)

new String((byte[]) arr) 
Harpreet
fuente
2
Si. Si solo necesita almacenar unicode como emojis en un determinado campo, la respuesta aceptada es demasiado intrusiva, simplemente cambie el campo text/ varchara a bloby listo. Locura por convertir charset y cotejo en toda la base de datos solo por eso :)
davidkonrad
9

Mi respuesta solo se suma a la respuesta de Selvamani P.

Es posible que también necesite cambiar cualquier SET NAMES utf8consulta con SET NAMES utf8mb4. Eso hizo el truco para mí.

Además, este es un gran artículo para portar su sitio web de utf8 a utf8mb4. En particular, el artículo destaca 2 puntos buenos sobre índices y tablas de reparación después de convertirlos a utf8mb4:

ÍNDICES

Al convertir de utf8 a utf8mb4, la longitud máxima de una columna o clave de índice no cambia en términos de bytes. Por lo tanto, es más pequeño en términos de caracteres, porque la longitud máxima de un carácter es ahora de cuatro bytes en lugar de tres. [...] El motor de almacenamiento InnoDB tiene una longitud máxima de índice de 767 bytes, por lo que para las columnas utf8 o utf8mb4, puede indexar un máximo de 255 o 191 caracteres, respectivamente. Si actualmente tiene columnas utf8 con índices de más de 191 caracteres, deberá indexar un número menor de caracteres cuando use utf8mb4.

TABLAS DE REPARACIÓN

Después de actualizar el servidor MySQL y realizar los cambios necesarios explicados anteriormente, asegúrese de reparar y optimizar todas las bases de datos y tablas. No hice esto de inmediato después de la actualización (no pensé que fuera necesario, ya que todo parecía funcionar bien a primera vista), y me encontré con algunos errores extraños en los que las declaraciones de ACTUALIZACIÓN no tenían ningún efecto, aunque no Se arrojaron errores.

Lea más sobre las consultas para reparar tablas en el artículo.

Nicola Pedretti
fuente
REPAIR TABLEy OPTIMIZE TABLEdebería ser innecesario, y ALTERtiene el efecto de hacerlo.
Rick James
5

El punto principal no se ha mencionado en las respuestas anteriores que,

Necesitamos pasar una cadena de consulta con las opciones "useUnicode=yes"y "characterEncoding=UTF-8"en la cadena de conexión

Algo como esto

mysql://USERNAME:PASSWORD@HOSTNAME:PORT/DATABASE_NAME?useUnicode=yes&characterEncoding=UTF-8
Ashh
fuente
5

Bueno, no necesita cambiar todo el conjunto de caracteres DB. En lugar de eso, puedes hacerlo cambiando la columna a blob tipo de .

ALTER TABLE messages MODIFY content BLOB;

usuario3855339
fuente
3

Tengo una buena solución para ahorrarle tiempo. También encuentro el mismo problema pero no pude resolver este problema con la primera respuesta.

Tu personaje definitivo es utf-8. Pero emoji necesita utf8mb4 para admitirlo. Si tiene permiso para revisar el archivo de configuración de mysql, puede seguir este paso.

Por lo tanto, realice el siguiente paso para actualizar su conjunto de caracteres (de utf-8 a utf8mb4).

paso 1. abre tu my.cnf para mysql, agrega estas líneas a tu my.cnf.

[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
init_connect='SET NAMES utf8mb4'

[mysql]
default-character-set = utf8mb4


[client]
default-character-set = utf8mb4

paso 2. detenga su servicio mysql e inicie el servicio mysql

mysql.server stop
mysql.server start

¡Terminado! Luego puedes verificar que tu personaje haya cambiado a utf8mb4.

mysql> SHOW VARIABLES LIKE 'character_set%';
+--------------------------+----------------------------------------------------------+
| Variable_name            | Value                                                    |
+--------------------------+----------------------------------------------------------+
| character_set_client     | utf8mb4                                                  |
| character_set_connection | utf8mb4                                                  |
| character_set_database   | utf8mb4                                                  |
| character_set_filesystem | binary                                                   |
| character_set_results    | utf8mb4                                                  |
| character_set_server     | utf8mb4                                                  |
| character_set_system     | utf8                                                     |
| character_sets_dir       | /usr/local/Cellar/mysql@5.7/5.7.29/share/mysql/charsets/ |
+--------------------------+----------------------------------------------------------+
8 rows in set (0.00 sec)
Tina Bri
fuente
2

Compatibilidad con Emoji para aplicaciones que tienen pila de tecnología: mysql, java, springboot, hibernate

Aplique los siguientes cambios en mysql para soporte unicode.

  1. ALTER DATABASE <database-name> CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
  2. ALTER TABLE <table-name> CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

Conexión DB - cambio de url jdbc:

jdbc:mysql://localhost:3306/<database-name>?useUnicode=yes&characterEncoding=UTF-8

Nota - Si el paso anterior no funciona, actualice la versión del conector mysql a 8.0.15. (mysql 5.7 funciona con la versión de conector 8.0.15 para soporte unicode)

usuario12359502
fuente
1

La solución más simple que funciona para mí es almacenar los datos como json_encode .

más tarde, cuando recupere, solo asegúrese de json_decode .

Aquí no tiene que cambiar la intercalación o el conjunto de caracteres de la base de datos y la tabla.

Siddhant
fuente
0

Para cualquiera que intente resolver esto en una instancia administrada de MySQL (en mi caso en AWS RDS), la forma más fácil era modificar el grupo de parámetros y establecer el conjunto de caracteres y la clasificación del servidor en utf8mb4y utf8mb4_bin, respectivamente. Después de reiniciar el servidor, una consulta rápida verifica la configuración de las bases de datos del sistema y las nuevas creadas:

SELECT * FROM information_schema.SCHEMATA S;
Myles Baker
fuente