Лучше всего использовать набор символов utf8mb4
с сопоставлением utf8mb4_unicode_ci
.
Набор символов, utf8
поддерживает только небольшое количество кодовых точек UTF-8, около 6% возможных символов. utf8
поддерживает только базовую многоязычную плоскость (BMP). Там 16 других самолетов. Каждая плоскость содержит 65 536 символов. utf8mb4
поддерживает все 17 самолетов.
MySQL будет обрезать 4-байтовые символы UTF-8, что приведет к повреждению данных.
Набор utf8mb4
символов был введен в MySQL 5.5.3 2010-03-24.
Некоторые из необходимых изменений для использования нового набора символов не являются тривиальными:
- Возможно, потребуется внести изменения в адаптер базы данных приложения.
- В my.cnf необходимо будет внести изменения, включая установку набора символов, сопоставление и переключение innodb_file_format на Barracuda.
- Операторы SQL CREATE могут включать в себя:
ROW_FORMAT=DYNAMIC
- DYNAMIC требуется для индексов на VARCHAR (192) и выше.
ПРИМЕЧАНИЕ. Для переключения Barracuda
с Antelope
, возможно, потребуется перезапустить службу MySQL более одного раза. innodb_file_format_max
не изменится до тех пор , после того , как служба MySQL перезапущена для: innodb_file_format = barracuda
.
MySQL использует старый Antelope
формат файла InnoDB. Barracuda
поддерживает динамические форматы строк, которые вам понадобятся, если вы не хотите нажимать на ошибки SQL для создания индексов и ключей после переключения на кодировку:utf8mb4
- # 1709 - Слишком большой размер столбца индекса. Максимальный размер столбца составляет 767 байт.
- # 1071 - Указанный ключ был слишком длинным; максимальная длина ключа 767 байт
Следующий сценарий был протестирован на MySQL 5.6.17: по умолчанию MySQL настроен так:
SHOW VARIABLES;
innodb_large_prefix = OFF
innodb_file_format = Antelope
Остановите службу MySQL и добавьте параметры в существующий my.cnf:
[client]
default-character-set= utf8mb4
[mysqld]
explicit_defaults_for_timestamp = true
innodb_large_prefix = true
innodb_file_format = barracuda
innodb_file_format_max = barracuda
innodb_file_per_table = true
# Character collation
character_set_server=utf8mb4
collation_server=utf8mb4_unicode_ci
Пример оператора SQL CREATE:
CREATE TABLE Contacts (
id INT AUTO_INCREMENT NOT NULL,
ownerId INT DEFAULT NULL,
created timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
modified timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
contact VARCHAR(640) NOT NULL,
prefix VARCHAR(128) NOT NULL,
first VARCHAR(128) NOT NULL,
middle VARCHAR(128) NOT NULL,
last VARCHAR(128) NOT NULL,
suffix VARCHAR(128) NOT NULL,
notes MEDIUMTEXT NOT NULL,
INDEX IDX_CA367725E05EFD25 (ownerId),
INDEX created (created),
INDEX modified_idx (modified),
INDEX contact_idx (contact),
PRIMARY KEY(id)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE = InnoDB ROW_FORMAT=DYNAMIC;
- Вы можете увидеть ошибку # 1709, сгенерированную для
INDEX contact_idx (contact)
if ROW_FORMAT=DYNAMIC
, удаленную из оператора CREATE.
ПРИМЕЧАНИЕ. Изменение индекса до первых 128 символов contact
исключает необходимость использования Barracuda сROW_FORMAT=DYNAMIC
INDEX contact_idx (contact(128)),
Также обратите внимание: когда говорится, что размер поля равен VARCHAR(128)
128 байтам. Вы можете использовать 128, 4-байтовые символы или 128, 1-байтовые символы.
Этот INSERT
оператор должен содержать 4-байтовый символ 'poo' в строке 2:
INSERT INTO `Contacts` (`id`, `ownerId`, `created`, `modified`, `contact`, `prefix`, `first`, `middle`, `last`, `suffix`, `notes`) VALUES
(1, NULL, '0000-00-00 00:00:00', '2014-08-25 03:00:36', '1234567890', '12345678901234567890', '1234567890123456789012345678901234567890', '1234567890123456789012345678901234567890', '12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678', '', ''),
(2, NULL, '0000-00-00 00:00:00', '2014-08-25 03:05:57', 'poo', '12345678901234567890', '💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩', '💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩', '💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩', '', ''),
(3, NULL, '0000-00-00 00:00:00', '2014-08-25 03:05:57', 'poo', '12345678901234567890', '💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩', '💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩', '123💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩', '', '');
Вы можете увидеть количество места, используемого в last
столбце:
mysql> SELECT BIT_LENGTH(`last`), CHAR_LENGTH(`last`) FROM `Contacts`;
+--------------------+---------------------+
| BIT_LENGTH(`last`) | CHAR_LENGTH(`last`) |
+--------------------+---------------------+
| 1024 | 128 | -- All characters are ASCII
| 4096 | 128 | -- All characters are 4 bytes
| 4024 | 128 | -- 3 characters are ASCII, 125 are 4 bytes
+--------------------+---------------------+
В вашем адаптере базы данных вы можете установить кодировку и параметры сортировки для вашего соединения:
SET NAMES 'utf8mb4' COLLATE 'utf8mb4_unicode_ci'
В PHP это будет установлено для: \PDO::MYSQL_ATTR_INIT_COMMAND
Ссылки: