Вставка 4-байтовых символов Юникода в MySQL/MariaDB

При попытке вставить ???? (например, 4-байтовый символ Юникода) и MySQL (5.7), и MariaDB (10.2/10.3/10.4) выдают одну и ту же ошибку:

Incorrect string value: '\xF0\x9F\x92\xA9'

Заявление:

mysql> insert into bob (test) values ('????');

Вот кодировка/сопоставление моей базы данных:

mysql> select @@collation_database;                                                                     +----------------------+
| @@collation_database |
+----------------------+
| utf8mb4_unicode_ci   |
+----------------------+
1 row in set (0.00 sec)

mysql> SELECT @@character_set_database;                                                                 +--------------------------+
| @@character_set_database |
+--------------------------+
| utf8mb4                  |
+--------------------------+
1 row in set (0.00 sec)

Набор символов сервера:

mysql> show global variables like '%character_set_server%'\G;                                           *************************** 1. row ***************************
Variable_name: character_set_server
        Value: utf8mb4

Таблица:

create table bob ( `test` TEXT NOT NULL );
mysql> SHOW FULL COLUMNS FROM bob;
+-------+------+--------------------+------+-----+---------+-------+---------------------------------+---------+
| Field | Type | Collation          | Null | Key | Default | Extra | Privileges                      | Comment |
+-------+------+--------------------+------+-----+---------+-------+---------------------------------+---------+
| test  | text | utf8mb4_unicode_ci | NO   |     | NULL    |       | select,insert,update,references |         |
+-------+------+--------------------+------+-----+---------+-------+---------------------------------+---------+
1 row in set (0.00 sec)

Может кто-то указать мне верное направление?


person Danny Kopping    schedule 06.04.2019    source источник
comment
Единственный способ заставить это работать — выполнить SET NAMES utf8mb4 перед моим INSERT. Это единственный способ?   -  person Danny Kopping    schedule 07.04.2019
comment
Кстати, кодовая точка — это 21 бит в наборе символов Unicode. Это кодировка символов Unicode UTF-8, в которой для некоторых кодовых точек используются 4 8-битных кодовых единицы. 4-байтовый символ Unicode звучит странно и неоднозначно с двумя единицами кода UTF-16 и 1 единицей кода UTF-32.   -  person Tom Blodget    schedule 07.04.2019
comment
@infomaniac - обычно «лучший» способ доступен в параметрах подключения, которые использует клиент. (Каждый клиент делает это по-своему.) SET NAMES — это запасной вариант, который работает, если у вас нет (или вы не используете) параметров соединения.   -  person Rick James    schedule 16.04.2019


Ответы (1)


Да, как вы прокомментировали, вам нужно использовать SET NAMES utf8mb4.

Ваш 4-байтовый символ должен пройти от вашего клиента через соединение с базой данных и в таблицу. Все они должны поддерживать utf8mb4. Если какой-то из них не поддерживает utf8mb4, то 4-х байтные символы не смогут пройти.

SET NAMES utf8mb4 заставляет сеанс базы данных ожидать, что клиенты отправят строку, используя эту кодировку. По умолчанию для character_set_client в MySQL 5.7 используется utf8, поэтому вам нужно установить его на utf8mb4.

В MySQL 8.0.1 и более поздних версиях character_set_client по умолчанию уже является utf8mb4, поэтому вам не нужно его менять.

person Bill Karwin    schedule 06.04.2019