Como posso inserir carinhas no MySQL (😊)

18

Estou no MySQL 5.5.21 e estou tentando inserir o caractere de rosto sorridente '\ xF0 \ x9F \ x98 \ x8A'. Mas para a minha vida, não consigo descobrir como fazê-lo.

De acordo com vários fóruns que eu tenho lido, é possível. Mas sempre que eu tento, os dados ficam truncados.

mysql> INSERT INTO hour  (  `title`,   `content`,   `guid` ,  `published` , `lang` ,  `type` ,  
       `indegree` ,  `lon` ,  `lat` ,  `state` ,  `country` , `hour`  )   
       VALUES ( "title" ,  "content 😊  content" ,  "guid" ,  1,  1,   
                     "WEBLOG",  1,  1,  1,  "state" ,  "country" ,  1 );
Query OK, 1 row affected, 2 warnings (0.00 sec)

mysql> show warnings;
+---------+------+-------------------------------------------------------------------------------+
| Level   | Code | Message                                                                       |
+---------+------+-------------------------------------------------------------------------------+
| Warning | 1366 | Incorrect string value: '\xF0\x9F\x98\x8A  ...' for column 'content' at row 1 |
| Warning | 1265 | Data truncated for column 'published' at row 1                                |
+---------+------+-------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

mysql> select LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
|           687302 |
+------------------+
1 row in set (0.00 sec)

mysql> select * from hour where id = 687302;
+--------+-------+----------+------+---------------------+
| id     | title | content  | guid | published           |
+--------+-------+----------+------+---------------------+
| 687302 | title | content  | guid | 0000-00-00 00:00:00 |
+--------+-------+----------+------+---------------------+
1 row in set (0.00 sec)

Mas minha definição de tabela é a seguinte.

CREATE TABLE `hour` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `title` varchar(255) CHARACTER SET utf8 NOT NULL,
  `content` text CHARACTER SET utf8 NOT NULL,
  `guid` varchar(255) CHARACTER SET utf8 NOT NULL,
  `published` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `lang` tinyint(3) unsigned NOT NULL,
  `type` enum('WEBLOG','MICROBLOG') CHARACTER SET utf8 DEFAULT NULL,
  `indegree` int(4) unsigned NOT NULL,
  `lon` float DEFAULT NULL,
  `lat` float DEFAULT NULL,
  `state` varchar(50) CHARACTER SET utf8 DEFAULT '',
  `country` varchar(50) CHARACTER SET utf8 DEFAULT '',
  `hour` int(2) DEFAULT NULL,
  `gender` enum('MALE','FEMALE') CHARACTER SET utf8 DEFAULT NULL,
  `time_zone` varchar(45) CHARACTER SET utf8 DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MEMORY AUTO_INCREMENT=687560 DEFAULT CHARSET=utf8mb4 KEY_BLOCK_SIZE=288 

Pode-se ver que estou usando CHARSET = utf8mb4. Certamente isso corrige problemas relacionados ao uso de caracteres de vários bytes?

Ok, então eu não percebi:

  `content` text CHARACTER SET utf8 NOT NULL,

Eu corrigi isso agora, mas ainda assim recebo resultados interessantes.

CREATE TABLE `hourtmp` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `title` varchar(255) CHARACTER SET utf8 NOT NULL,
  `content` text NOT NULL,
  `guid` varchar(255) CHARACTER SET utf8 NOT NULL,
  `published` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `lang` tinyint(3) unsigned NOT NULL,
  `type` enum('WEBLOG','MICROBLOG') CHARACTER SET utf8 DEFAULT NULL,
  `indegree` int(4) unsigned NOT NULL,
  `lon` float DEFAULT NULL,
  `lat` float DEFAULT NULL,
  `state` varchar(50) CHARACTER SET utf8 DEFAULT '',
  `country` varchar(50) CHARACTER SET utf8 DEFAULT '',
  `hour` int(2) DEFAULT NULL,
  `gender` enum('MALE','FEMALE') CHARACTER SET utf8 DEFAULT NULL,
  `time_zone` varchar(45) CHARACTER SET utf8 DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MEMORY AUTO_INCREMENT=687563 DEFAULT CHARSET=utf8mb4 KEY_BLOCK_SIZE=288 |

 mysql> INSERT INTO hourtmp  (  `title`,   `content`,   `guid` ,  `published` , `lang` ,  `type` ,  `indegree` ,  
 `lon` ,  `lat` ,  `state` ,  `country` , `hour`  )   VALUES ( "title" ,  "content 😊  content" ,  
 "guid" ,  1,  1,   "WEBLOG",  1,  1,  1,  "state" ,  "country" ,  1 );
 Query OK, 1 row affected, 2 warnings (0.00 sec)

 mysql> show warnings;

 | Level   | Code | Message                                                                       |

 | Warning | 1366 | Incorrect string value: '\xF0\x9F\x98\x8A  ...' for column 'content' at row 1 |
 | Warning | 1265 | Data truncated for column 'published' at row 1                                |

 2 rows in set (0.00 sec)

 mysql> select * from hourtmp;
 +--------+-------+-----------------------+
 | id     | title | content               |
 +--------+-------+-----------------------+
 | 687560 | title | content ????  content |
 | 687561 | title | content ????  content |
 +--------+-------+-----------------------+
Bryan Hunt
fonte
Estou eliminando todos os caracteres especiais na camada de aplicativos agora, portanto não é um problema para mim. Mas, eu gostaria de saber se é possível, de alguma forma, obter os dados dentro e fora do MySQL.
11119 Bryan Hunt
Não é um cara MySQL, mas não pode especificar uft8para o TEXTcampo bem
JNK
você executou nomes de conjunto utf8mb4; do seu cliente antes de emitir a inserção?
Atxdba 12/07/12
JNK, o campo de texto está usando a tabela padrão, neste caso, utf8mb4.
Bryan Hunt
atxdba. Obrigado pela sugestão, ainda aparece como?, O que presumivelmente significa corrompido. Droga, esses emoticons / decepticons! ;)
Bryan Hunt

Respostas:

22

Eu escrevi recentemente um guia detalhado sobre como mudar do MySQL utf8parautf8mb4 . Se você seguir as etapas, tudo deverá funcionar corretamente. Aqui estão os links diretos para cada etapa individual do processo:

Suspeito que o seu problema possa ser resolvido seguindo o passo 5. Espero que ajude!

Mathias Bynens
fonte
1
Deixou esse trabalho tão incapaz de testar / verificar. No entanto, suspeito que a configuração collation-server = utf8mb4_unicode_ci é o que estava faltando. Bom tutorial!
Bryan Hunt
Muito bom Mathias. Um lembrete para as pessoas: os detalhes da conexão do cliente são importantes. Estou usando o módulo NPM mysqldo Node e precisava especificar charset: 'utf8mb4'na minha createConnection()chamada, caso contrário, a inserção de caracteres UTF8 verdadeiros ainda falharia com o Incorrect string valueerro, mesmo depois de converter a tabela e a coluna em utf8mb4conjunto e agrupamento de caracteres. Espero que os detalhes do nível de configuração do cliente na Etapa 5 tenham efeito semelhante.
Neek
2

Faça o seguinte:

  1. Defina o charset do banco de dados como utf8mb4

  2. Defina o conjunto de caracteres da coluna como utf8mb4

como abaixo da consulta:

ALTER TABLE `comments` CHANGE `text` `text` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL;
Poonam Gupta
fonte
Essas etapas são realmente suficientes? A resposta aceita tem muito mais.
Colin 'Hart
Depende do problema, se o problema estava no lado do banco de dados, isso é suficiente. Mas também pode ser um problema de conexão com o cliente.
Spydon