Como armazenar caracteres Emoji no banco de dados MySQL

172

Estou usando o caractere Emoji no meu projeto. Esses caracteres são salvos (??) no banco de dados mysql. Eu tinha usado o agrupamento padrão do banco de dados em utf8mb4_general_ci. Isso mostra

1366 Valor incorreto da string: '\ xF0 \ x9F \ x98 \ x83 \ xF0 \ x9F ...' para a coluna 'comment' na linha 1

Selvamani P
fonte
1
Como você está salvando seus dados? Você pode nos mostrar esse código?
Tomas Buteler 13/09/16
1
Obrigado por seu comentário. Eu encontrei a solução para essa coleção padrão do Change Database como ** utf8mb4 ** e também a coleção Change Table 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'Defina utf8mb4 na conexão com o banco de dados: $database_connection = new mysqli($server, $user,$password,$database_name); $database_connection->set_charset("utf8mb4");
Selvamani P

Respostas:

29

etapa 1, altere o conjunto de caracteres padrão do seu banco de dados:

ALTER DATABASE database_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;

etapa 2, defina charset ao criar a tabela:

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

ou alterar tabela

ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE table_name modify name text charset utf8mb4;
ospider
fonte
Eu segui essas consultas e parei e reiniciei o servidor mysql, mas quando tento inserir emojis na minha tabela ainda recebo o mesmo erro. Todos os comandos foram bem-sucedidos, exceto o INSERT. INSERIR EM Entradas (data, hora, legenda) VALORES (2018-05-20 ', '12: 38: 00', 'Descrição do teste com emoji: 😊❤️'); As configurações da coluna são Collation: utf8mb4_0900_ai_ci Definição: texto da descrição
1
Sua conexão também precisa ser utf8mb4 e não utf8 para que funcione.
Henrik Hansen
3
@ospider, na etapa 2 você usa utfmb4_general_ci em vez de unicode - qualquer motivo?
21918 Warren
263

1) Banco de dados: altere o agrupamento padrão do banco de dados como utf8mb4.

2) Tabela: Altere o agrupamento da tabela como CHARACTER SET utf8mb4 COLLATE utf8mb4_bin.

Inquerir:

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) Defina utf8mb4na conexão com o banco de dados:

  $database_connection = new mysqli($server, $user, $password, $database_name); 
  $database_connection->set_charset('utf8mb4');
Selvamani P
fonte
4
É possível sem alterar a coleção padrão do banco de dados?
AliN11
23
Isso não está funcionando para mim. Estou obtendo "???" em vez de smilies. somente "☺" isso chegou ao banco de dados com segurança.
Curious Developer
10
Pode ser necessário atualizar não apenas a tabela para utf8mb4, mas TAMBÉM as próprias colunas, caso contrário elas ainda podem aparecer como ?? em vez de 💙.
Ael
2
Funcionou para mim, mas não se esqueça de reiniciar o MySQL.
Ravi Misra 12/09
8
Preciso correr SET NAMES utf8mb4;para começar a salvar emoticons; antes desse comando, ele estava salvando-os como??
#
18

Os bancos de dados e as tabelas devem ter conjunto de caracteres utf8mb4e agrupamento utf8mb4_unicode_ci.

Ao criar um novo banco de dados, você deve usar:

CREATE DATABASE mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

Se você possui um banco de dados existente e deseja adicionar suporte:

ALTER DATABASE database_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;

Você também precisa definir o conjunto de caracteres e agrupamento corretos para suas tabelas:

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

ou altere-o se você tiver tabelas existentes com muitos dados:

ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

Observe que utf8_general_cinão é mais a melhor prática recomendada. Veja as perguntas e respostas relacionadas:

Qual é a diferença entre utf8_general_ci e utf8_unicode_ci no Stack Overflow.

samawaat
fonte
Eu tenho um banco de dados e uma tabela contendo data.and ao executar a segunda alteração, diz que: ERRO 1833 (HY000): Não é possível alterar a coluna 'id': usada em uma restrição de chave estrangeira 'FK12njtf8e0jmyb45lqfpt6ad89' da tabela 'lizbazi.post'
Seyyed Mahdiyar Zerehpoush
@SeyyedMahdiyarZerehpoush - talvez você consiga limitar sua atualização a colunas específicas que a exigem, conforme descrito aqui: stackoverflow.com/a/15781925/1247581 por exemploALTER TABLE mytable MODIFY my_emoji_friendly_text_column VARCHAR(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
theartofrain
qualquer diff ao usar utf8mb4_binvs utf8mb4_unicode_cipara as colunas?
Muhammad Omer Aslam
14

Se você estiver usando Solr + Mysql + Java, poderá usar:

Isso pode ser usado:

  • case1: Quando você não deseja alterar o DB.
  • case2: quando você precisa importar emoticons do seu núcleo do Mysql para o Solr.

No caso acima, esta é uma das soluções para armazenar seus emoticons no seu sistema.

Passos para usá-lo:

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

  1. Use urlEncoder para codificar sua String com emoticons.
  2. Armazene-o no banco de dados sem alterar o MysqlDB.
  3. Você pode armazená-lo no núcleo solr (forma decodificada), se desejar, ou pode armazenar a forma codificada.
  4. Ao buscar esses emoticons do núcleo do DB ou Solr, você pode decodificá-lo usando o urlDecoder.

Exemplo 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
fonte
Obrigado por este trecho de código, que pode fornecer ajuda imediata e limitada. Uma explicação adequada melhoraria bastante seu valor a longo prazo, mostrando por que essa é uma boa solução para o problema e a tornaria mais útil para futuros leitores com outras perguntas semelhantes. Por favor edite sua resposta para adicionar alguma explicação, incluindo as suposições que você fez.
perfil completo de Toby Speight
1
trabalho como um encanto, eu usei-o no modelo, então eu realmente não precisa alterar qualquer código e banco de dados somente o modelo de dados sobre o setter e getter do conteúdo
bowpunya
1
As chamadas de função de codificação / decodificação tendem a causar problemas. Em vez disso, corrija as configurações do conjunto de caracteres nos vários locais.
Rick James
1
Isso não está resolvendo o problema, está ignorando-o. E você encontrará vários problemas com esse método; por exemplo, você desacelerará seu aplicativo porque precisará decodificar e codificar tudo. Além disso, se você digitar o caractere %, sua decodificação será interrompida.
Jonathan Laliberte
14

Atualizei meu banco de dados e tabela para atualizar de utf8 para utf8mb4 . Mas nada funciona para mim. Então tentei atualizar o tipo de dados da coluna para blob , felizmente funcionou para mim e os dados foram salvos. Até meu banco de dados e tabela são CHARACTER SET utf8 COLLATE utf8_unicode

Deepak Arora
fonte
13

O comando para modificar a coluna é:

ALTER TABLE TABLE_NAME MODIFY COLUMN_NAME TYPE;

E precisamos usar type = BLOB

O exemplo a ser modificado é o seguinte: -

ALTER TABLE messages MODIFY content BLOB;

Eu verifiquei se o mySQL e outros bancos de dados mais recentes não precisam ''ser usados ​​no comando table_name, column_name etc.

Buscar e salvar dados: salve diretamente o conteúdo do bate-papo na coluna e para recuperar dados, busque dados como matriz de bytes (byte[])da coluna db e depois converta-os em, stringpor exemplo, (código Java)

new String((byte[]) arr) 
Harpreet
fonte
2
Sim. Se você só precisa armazenar unicode como emojis em um determinado campo, a resposta aceita é muito intrusiva. Simplesmente altere o campo text/ varcharpara a blobe pronto. Loucura charset converter e agrupamento em todo o DB apenas para que :)
davidkonrad
9

Minha resposta só contribui para a resposta Selvamani P.

Você também pode precisar alterar as SET NAMES utf8consultas SET NAMES utf8mb4. Isso fez o truque para mim.

Além disso, este é um ótimo artigo para portar seu site de utf8 para utf8mb4. Em particular, o artigo faz 2 bons pontos nos índices e nas tabelas de reparo após convertê-los em utf8mb4:

ÍNDICES

Ao converter de utf8 em utf8mb4, o comprimento máximo de uma coluna ou chave de índice é inalterado em termos de bytes. Portanto, é menor em termos de caracteres, porque agora o comprimento máximo de um caractere é de quatro bytes em vez de três. [...] O mecanismo de armazenamento do InnoDB possui um comprimento máximo de índice de 767 bytes; portanto, para colunas utf8 ou utf8mb4, é possível indexar um máximo de 255 ou 191 caracteres, respectivamente. Se você atualmente possui utf8 colunas com índices maiores que 191 caracteres, será necessário indexar um número menor de caracteres ao usar utf8mb4.

MESAS DE REPARAÇÃO

Após atualizar o servidor MySQL e fazer as alterações necessárias explicadas acima, certifique-se de reparar e otimizar todos os bancos de dados e tabelas. Não fiz isso imediatamente após a atualização (não achei que fosse necessário, pois tudo parecia funcionar bem à primeira vista) e me deparei com alguns erros estranhos em que as instruções UPDATE não tinham efeito, mesmo que não erros foram lançados.

Leia mais sobre as consultas para reparar tabelas no artigo.

Nicola Pedretti
fonte
REPAIR TABLEe OPTIMIZE TABLEdeve ser desnecessário - e ALTERtem o efeito de fazê-las.
Rick James
5

O ponto principal não foi mencionado nas respostas acima que,

Precisamos passar a string de consulta com as opções "useUnicode=yes"e "characterEncoding=UTF-8"na string de conexão

Algo assim

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

Bem, você não precisa alterar o conjunto completo de banco de dados. Em vez disso, você pode fazer isso alterando a coluna para o tipo de blob .

Mensagens ALTER TABLE MODIFICAR BLOB de conteúdo;

user3855339
fonte
3

Eu tenho uma boa solução para economizar seu tempo. Também encontro o mesmo problema, mas não consegui resolver esse problema pela primeira resposta.

Seu personagem com defeito é utf-8. Mas o emoji precisa de utf8mb4 para suportá-lo. Se você tiver permissão para revisar o arquivo de configuração do mysql, poderá seguir esta etapa.

Portanto, siga estas etapas para atualizar seu conjunto de caracteres (de utf-8 para utf8mb4).

passo 1. abra seu my.cnf para o mysql, adicione estas linhas ao seu 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

passo 2. interrompa seu serviço mysql e inicie o serviço mysql

mysql.server stop
mysql.server start

Acabado! Então você pode verificar se seu personagem foi alterado para 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
fonte
2

Suporte a emoji para aplicativos com pilha tecnológica - mysql, java, springboot, hibernate

Aplique as alterações abaixo no mysql para suporte ao 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;

Conexão com o banco de dados - alteração de URL do jdbc:

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

Nota - Se a etapa acima não estiver funcionando, atualize a versão do mysql-connector para 8.0.15. (o mysql 5.7 funciona com o conector versão 8.0.15 para suporte a unicode)

user12359502
fonte
1

A solução mais simples que funciona para mim é armazenar os dados como json_encode .

mais tarde, quando você recuperar, certifique-se de json_decode .

Aqui você não precisa alterar o agrupamento ou o conjunto de caracteres do banco de dados e da tabela.

Siddhant
fonte
0

Para quem tenta resolver isso em uma instância gerenciada do MySQL (no meu caso no AWS RDS), a maneira mais fácil era modificar o grupo de parâmetros e definir o conjunto de caracteres e o agrupamento do servidor como utf8mb4e utf8mb4_bin, respectivamente. Após reiniciar o servidor, uma consulta rápida verifica as configurações dos bancos de dados do sistema e dos recém-criados:

SELECT * FROM information_schema.SCHEMATA S;
Myles Baker
fonte