Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MySQL utf8mb4, Errors when saving Emojis

I try to save names from users from a service in my MySQL database. Those names can contain emojis like 🙈😂😱🍰 (just for examples)

After searching a little bit I found this stackoverflow linking to this tutorial. I followed the steps and it looks like everything is configured properly.

I have a Database (charset and collation set to utf8mb4 (_unicode_ci)), a Table called TestTable, also configured this way, as well as a "Text" column, configured this way (VARCHAR(191) utf8mb4_unicode_ci).

When I try to save emojis I get an error:

Example of error for shortcake (🍰):     Warning: #1300 Invalid utf8 character string: 'F09F8D'     Warning: #1366 Incorrect string value: '\xF0\x9F\x8D\xB0' for column 'Text' at row 1 

The only Emoji that I was able to save properly was the sun ☀️

Though I didn't try all of them to be honest.

Is there something I'm missing in the configuration?

Please note: All tests of saving didn't involve a client side. I use phpmyadmin to manually change the values and save the data. So the proper configuration of the client side is something that I will take care of after the server properly saves emojis.

Another Sidenote: Currently, when saving emojis I either get the error like above, or get no error and the data of Username 🍰 will be stored as Username ????. Error or no error depends on the way I save. When creating/saving via SQL Statement I save with question marks, when editing inline I save with question marks, when editing using the edit button I get the error.

thank you

EDIT 1: Alright so I think I found out the problem, but not the solution. It looks like the Database specific variables didn't change properly.

When I'm logged in as root on my server and read out the variables (global):
Query used: SHOW VARIABLES WHERE Variable_name LIKE 'character\_set\_%' OR Variable_name LIKE 'collation%';

+--------------------------+--------------------+ | 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               | | collation_connection     | utf8mb4_unicode_ci | | collation_database       | utf8mb4_unicode_ci | | collation_server         | utf8mb4_unicode_ci | +--------------------------+--------------------+ 10 rows in set (0.00 sec) 

For my Database (in phpmyadmin, the same query) it looks like the following:

+--------------------------+--------------------+ | Variable_name            | Value              | +--------------------------+--------------------+ | character_set_client     | utf8               | | character_set_connection | utf8mb4            | | character_set_database   | utf8mb4            | | character_set_filesystem | binary             | | character_set_results    | utf8               | | character_set_server     | utf8               | | character_set_system     | utf8               | | collation_connection     | utf8mb4_unicode_ci | | collation_database       | utf8mb4_unicode_ci | | collation_server         | utf8mb4_unicode_ci | +--------------------------+--------------------+ 

How can I adjust these settings on the specific database? Also even though I have the first shown settings as default, when creating a new database I get the second one as settings.

Edit 2:

Here is my my.cnf file:

[client] port=3306 socket=/var/run/mysqld/mysqld.sock default-character-set = utf8mb4  [mysql] default-character-set = utf8mb4  [mysqld_safe] socket=/var/run/mysqld/mysqld.sock  [mysqld] user=mysql pid-file=/var/run/mysqld/mysqld.pid socket=/var/run/mysqld/mysqld.sock port=3306 basedir=/usr datadir=/var/lib/mysql tmpdir=/tmp lc-messages-dir=/usr/share/mysql log_error=/var/log/mysql/error.log max_connections=200 max_user_connections=30 wait_timeout=30 interactive_timeout=50 long_query_time=5 innodb_file_per_table character-set-client-handshake = FALSE character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci  !includedir /etc/mysql/conf.d/ 
like image 338
Loki Avatar asked Feb 01 '16 08:02

Loki


People also ask

Should I use utf8mb4 or utf8?

The difference between utf8 and utf8mb4 is that the former can only store 3 byte characters, while the latter can store 4 byte characters. In Unicode terms, utf8 can only store characters in the Basic Multilingual Plane, while utf8mb4 can store any Unicode character.

Can utf8 store Emoji?

The unicodes for emoticons are fully supported by the UTF-8 encoding; however, MySQL's utf8 does not! To save emoticons to a MySQL database we need to use utf8mb4 .


1 Answers

character_set_client, _connection, and _results must all be utf8mb4 for that shortcake to be eatable.

Something, somewhere, is setting a subset of those individually. Rummage through my.cnf and phpmyadmin's settings -- something is not setting all three.

If SET NAMES utf8mb4 is executed, all three set correctly.

The sun shone because it is only 3-bytes - E2 98 80; utf8 is sufficient for 3-byte utf8 encodings of Unicode characters.

like image 117
Rick James Avatar answered Sep 28 '22 04:09

Rick James