Jak wstawić buźki do MySQL (😊)

18

Korzystam z MySQL 5.5.21 i próbuję wstawić znak buźki „\ xF0 \ x9F \ x98 \ x8A”. Ale przez całe życie nie mogę wymyślić, jak to zrobić.

Według różnych forów, które czytałem, jest to możliwe. Ale ilekroć spróbuję, dane są po prostu obcięte.

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)

Ale moja definicja tabeli jest następująca.

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 

Widać, że używam CHARSET = utf8mb4. Czy to naprawia problemy związane z używaniem znaków wielobajtowych?

Ok, więc nie zauważyłem:

  `content` text CHARACTER SET utf8 NOT NULL,

Poprawiłem to teraz, ale nadal mam fajne wyniki.

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
źródło
Teraz usuwam wszystkie znaki specjalne w warstwie aplikacji, więc nie jest to dla mnie problemem. Chciałbym jednak wiedzieć, czy da się w jakiś sposób pobrać i wyjąć dane z MySQL.
Bryan Hunt
Nie jestem facetem z MySQL, ale nie możesz też podać uft8tego TEXTpola
JNK,
czy uruchomiłeś ustawione nazwy utf8mb4; od twojego klienta przed wydaniem wkładki?
atxdba
JNK, pole tekstowe używa domyślnej tabeli, w tym przypadku utf8mb4.
Bryan Hunt
atxdba. Dzięki za sugestię, nadal pojawia się jako?, Co prawdopodobnie oznacza zepsucie. Cholera, te emotikony / decepticony! ;)
Bryan Hunt

Odpowiedzi:

22

Niedawno napisałem szczegółowy przewodnik na temat przejścia z MySQL utf8nautf8mb4 . Jeśli wykonasz podane tam czynności, wszystko powinno działać poprawnie. Oto bezpośrednie linki do poszczególnych kroków procesu:

Podejrzewam, że problem można rozwiązać, wykonując krok 5. Mam nadzieję, że to pomoże!

Mathias Bynens
źródło
1
Opuściłem to zadanie, więc nie mogę przetestować / zweryfikować. Podejrzewam jednak, że brakowało ustawienia collation-server = utf8mb4_unicode_ci. Dobry samouczek!
Bryan Hunt
Bardzo miły Mathias. Przypomnienie dla ludzi, szczegóły połączenia z klientem mają znaczenie. Korzystam z modułu NPM mysqlz węzła i musiałem określić charset: 'utf8mb4'w swoim createConnection()wywołaniu, w przeciwnym razie wstawienie prawdziwych znaków UTF8 nadal nie powiodło się z Incorrect string valuebłędem, nawet po przekonwertowaniu tabeli i kolumny na utf8mb4zestaw znaków i zestawianie. Oczekuję, że szczegóły poziomu konfiguracji klienta w kroku 5 będą miały podobny efekt.
Neek
2

Wykonaj następujące czynności:

  1. Ustaw zestaw znaków bazy danych na utf8mb4

  2. Ustaw zestaw znaków kolumny na utf8mb4

jak poniżej zapytanie:

ALTER TABLE `comments` CHANGE `text` `text` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL;
Poonam Gupta
źródło
Czy te kroki są naprawdę wystarczające? Przyjęta odpowiedź ma znacznie więcej.
Colin 't Hart
Zależy od tego, jaki był problem, jeśli problem był po stronie bazy danych, wystarczy. Ale równie dobrze może to stanowić problem z połączeniem klienta.
spydon