В чем разница между кодировками utf8mb4 и utf8 в MySQL?

В чем разница между кодировками utf8mb4 и utf8 в MySQL?

Я уже знаю о кодировках ASCII, UTF-8, UTF-16 и UTF-32; но мне любопытно узнать, в чем разница utf8mb4 группы кодировок с другими типами кодирования, определенными в MySQL Server.

Есть ли какие-либо особые преимущества / предложения по использованию utf8mb4 вместо utf8?


person Mojtaba Rezaeian    schedule 06.05.2015    source источник
comment
Прочтите, чтобы понять разницу: eversql.com/   -  person Shiwangini    schedule 13.03.2021


Ответы (5)


UTF-8 - это кодировка переменной длины. В случае UTF-8 это означает, что для хранения одной кодовой точки требуется от одного до четырех байтов. Однако кодировка MySQL под названием utf8 (псевдоним utf8mb3) хранит не более трех байтов на одну кодовую точку.

Таким образом, набор символов utf8 / utf8mb3 не может хранить все кодовые точки Unicode: он поддерживает только диапазон от 0x000 до 0xFFFF, который называется Базовая многоязычная плоскость. См. Также Сравнение кодировок Unicode.

Это то, что (предыдущая версия той же страницы по адресу) в документации MySQL говорится об этом:

Набор символов с именем utf8 [/ utf8mb3] использует максимум три байта на символ и содержит только символы BMP. Начиная с MySQL 5.5.3, набор символов utf8mb4 использует максимум четыре байта на символ, поддерживает дополнительные символы:

  • Для символа BMP utf8 [/ utf8mb3] и utf8mb4 имеют одинаковые характеристики хранения: одинаковые значения кода, одинаковая кодировка, одинаковая длина.

  • Для дополнительного символа utf8 [/ utf8mb3] не может хранить этот символ вообще, тогда как utf8mb4 требует четыре байта для его хранения. Поскольку utf8 [/ utf8mb3] вообще не может хранить символ, у вас нет дополнительных символов в столбцах utf8 [/ utf8mb3], и вам не нужно беспокоиться о преобразовании символов или потере данных при обновлении данных utf8 [/ utf8mb3] из более старых версий MySQL.

Итак, если вы хотите, чтобы ваш столбец поддерживал хранение символов, лежащих за пределами BMP (а вы обычно этого хотите), например emoji используйте utf8mb4. См. Также Какие наиболее распространенные не -BMP Unicode-символы используются в действительности?.

person CodeCaster    schedule 06.05.2015
comment
Единственные случаи, с которыми я столкнулся (пока), когда utf8mb4 был «обязательным», - это китайский язык и смайлики. Есть малоизвестные алфавиты, которым это нужно. - person Rick James; 06.05.2015
comment
Это также необходимо, если вы используете для хранения зашифрованных паролей и данных в своей базе данных. Я хранил зашифрованный пароль в mysql с использованием обычного формата utf8, что доставляло мне много проблем с некоторыми паролями случайным образом и было очень трудно отлаживать, поэтому, наконец, я попытался использовать кодировку base64 и временно исправил проблему. Но теперь я знаю причину. - person Mojtaba Rezaeian; 20.01.2016
comment
Зашифрованные данные @idealidea являются двоичными, и вы не должны хранить двоичные данные в столбце varchar. :) - person CodeCaster; 20.01.2016
comment
Можете ли вы добавить, какие смайлы работают в utf8, а какие нет? - person User; 20.12.2016
comment
@User все символы BMP помещаются в столбец MySQL UTF8. Если в BMP есть смайлы, они будут работать. - person CodeCaster; 20.12.2016
comment
@thomasrutter Попробуйте этот символ (????) для сохранения в UTF-8. :) - person 502_Geek; 27.03.2018
comment
@MojtabaRezaeian это несколько зависит от алгоритма пароля - bcrypt2 будет выдавать ASCII. - person Jasen; 15.06.2018
comment
@ D3adL0cK - Спасибо за пример. Китайский иероглиф ???? шестнадцатеричный F0A19EB0, требующий utf8mb4. - person Rick James; 29.01.2019
comment
@thomasrutter Китайские + корейские + японские иероглифы - это не все в базовой многоязычной плоскости. - person Simon Hi; 01.02.2019
comment
Говоря, что он поддерживает только диапазон от 0x000 до 0xFFFF, он хранит максимум три байта на кодовую точку, но 0xFFFF имеет только два байта, где другой байт? - person http8086; 21.07.2019
comment
@work, потому что кодовую точку нужно закодировать в байты. Чтобы указать, что это первая часть многобайтовой кодовой точки, нужно несколько битов, далее следуют другие байты. См. Также fileformat.info/info/unicode/char/ffff/index. htm и fileformat.info/info/unicode/utf8.htm. - person CodeCaster; 21.07.2019
comment
@thomasrutter Обратите внимание, что в Unicode 12.1.0 имеется 89092 китайско-японско-корейских символа, что намного больше, чем может представлять 0x0000-0xFFFF. «????» (U + 217B0) - это пример символа SIP CJK. - person Star Brilliant; 18.09.2019
comment
Я столкнулся с проблемами с лигатурами (например, æ) и даже с диакритическими символами при копировании текста из PDF-файлов с нестандартными шрифтами в базу данных mySQL - я подозреваю, что это связано с этой проблемой. - person Jeremy Young; 29.03.2021

Набор символов utf8mb4 полезен, потому что в настоящее время нам нужна поддержка для хранения не только языковых символов, но и символов, недавно представленных смайлов и т. Д.

Хорошее прочтение Матиаса Биненса Как поддерживать полный Unicode в базах данных MySQL также может пролить свет на это.

person Jimmy Kane    schedule 31.10.2016
comment
MySQL 8.0 теперь по умолчанию использует набор символов utf8mb4. [mysql.com/products/enterprise/techspec.html] - person Ahmed Rezk; 29.05.2018

Взято из Справочного руководства MySQL 8.0:

  • utf8mb4: кодировка UTF-8 набора символов Unicode с использованием от одного до четырех байтов на символ.

  • utf8mb3: кодировка UTF-8 набора символов Unicode с использованием от одного до трех байтов на символ.

В MySQL utf8 в настоящее время является псевдонимом для utf8mb3, который устарел и будет удален в будущем выпуске MySQL. В этот момент utf8 станет ссылкой на utf8mb4.

Таким образом, независимо от этого псевдонима вы можете сознательно установить кодировку utf8mb4.

Чтобы завершить ответ, я хотел бы добавить ниже комментарий @ WilliamEntriken (также взятый из руководства):

Чтобы избежать двусмысленности в значении utf8, подумайте о том, чтобы явно указать utf8mb4 для ссылок на набор символов вместо utf8.

person simhumileco    schedule 14.09.2018

  • utf8 - это более старая и ошибочная реализация UTF-8 в MySQL, которая уже устарела.
  • utf8mb4 - это то, что они назвали своей фиксированной реализацией UTF-8, и это то, что вы должны использовать прямо сейчас.

В их некорректной версии работают только символы в первой плоскости 64k символов - базовой многоязычной плоскости, а другие символы считаются недопустимыми. Значения кодовой точки в этой плоскости - от 0 до 65535 (некоторые из которых зарезервированы по особым причинам) могут быть представлены многобайтовыми кодировками в UTF-8 размером до 3 байтов, и ранняя версия MySQL UTF-8 произвольно решила установите это как предел. Это ограничение ни в коем случае не было правильной интерпретацией правил UTF-8, потому что UTF-8 никогда не определялся как разрешающий только до 3 байтов на символ. Фактически, самые ранние определения UTF-8 определяли его как имеющий до 6 байтов (с момента пересмотра до 4). Исходная версия MySQL всегда была произвольно повреждена.

Когда MySQL выпустил это, последствия этого ограничения были не так уж плохи, так как большинство символов Unicode находились на этом первом уровне. С тех пор в Юникод добавлялось все больше и больше вновь определенных диапазонов символов со значениями за пределами этой первой плоскости. Сам Unicode определяет 17 плоскостей, хотя пока используются только 7 из них.

Чтобы не нарушить старый код, сделав какие-либо конкретные предположения, MySQL сохранил сломанную реализацию и назвал новую фиксированную версию utf8mb4. Это привело к некоторой путанице с неправильным толкованием имени, как если бы оно было своего рода расширением UTF-8 или альтернативной формой UTF-8, а не реализацией истинного UTF-8 в MySQL.

В будущих версиях MySQL в конечном итоге будет постепенно отказываться от старой версии, и на данный момент она может считаться устаревшей. В обозримом будущем вам необходимо использовать utf8mb4, чтобы обеспечить правильную кодировку UTF-8. По прошествии достаточного времени текущий utf8 будет удален, и в какой-то момент в будущем utf8 снова вырастет, на этот раз со ссылкой на фиксированную версию, хотя utf8mb4 по-прежнему будет однозначно относиться к фиксированной версии.

person thomasrutter    schedule 05.10.2020

MySQL добавил этот код utf8mb4 после 5.5.3, Mb4 - это максимальное значение 4 байта, специально разработанное для совместимости с четырехбайтовым Unicode. К счастью, UTF8MB4 является расширенным набором UTF8, за исключением того, что нет необходимости преобразовывать кодировку в UTF8MB4. Конечно, для экономии места достаточно общего использования UTF8.

Исходный формат UTF-8 использует от одного до шести байтов и может кодировать максимум 31 символ. Последняя спецификация UTF-8 использует от одного до четырех байтов и может кодировать до 21 бита только для представления всех 17 плоскостей Unicode. UTF8 - это набор символов в Mysql, который поддерживает не более трех байтов символов UTF-8, которые являются базовой многотекстовой плоскостью в Юникоде.

Чтобы сохранить символы UTF-8 длиной 4 байта в Mysql, вам необходимо использовать набор символов UTF8MB4, но только 5.5. После того, как поддерживаются 3 версии (Просмотр версии: Выбрать версию ();). Я думаю, что для лучшей совместимости всегда следует использовать UTF8MB4 вместо UTF8. Для данных типа char UTF8MB4 занимает больше места и, согласно официальной рекомендации Mysql, использует VARCHAR вместо char.

В MariaDB utf8mb4 в качестве CHARSET по умолчанию, если он не установлен явно в конфигурации сервера, поэтому используется COLLATE utf8mb4_unicode_ci.

Обратитесь к MariaDB CHARSET и COLLATE Click

CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
person AppCloudData    schedule 22.07.2020
comment
Нет. В MariaDB CHARSET по умолчанию - latin1. (Если ваш дистрибутив не исправил это за вас.) mariadb.com/kb/en/character-set-and-collation-overview/ - person Cedric Sun; 21.10.2020