Найкраще використовувати набір символів utf8mb4
із зіставленням utf8mb4_unicode_ci
.
Набір символів, utf8
підтримує лише невелику кількість кодових точок UTF-8, приблизно 6% можливих символів. utf8
підтримує лише базову багатомовну площину (BMP). Там ще 16 літаків. Кожна площина містить 65 536 символів. utf8mb4
підтримує всі 17 літаків.
MySQL уріже 4 байтові символи UTF-8, що призведе до пошкодження даних.
The 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)
якщо 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
Список літератури: