Il est préférable d'utiliser le jeu de caractères utf8mb4
avec le classement utf8mb4_unicode_ci
.
Le jeu de caractères utf8
, ne prend en charge qu'une petite quantité de points de code UTF-8, soit environ 6% des caractères possibles. utf8
prend uniquement en charge le plan multilingue de base (BMP). Il y a 16 autres avions. Chaque avion contient 65 536 caractères. utf8mb4
prend en charge les 17 avions.
MySQL tronquera les caractères UTF-8 de 4 octets résultant en des données corrompues.
Le utf8mb4
jeu de caractères a été introduit dans MySQL 5.5.3 le 24/03/2010.
Certaines des modifications requises pour utiliser le nouveau jeu de caractères ne sont pas anodines:
- Des modifications peuvent devoir être apportées à votre adaptateur de base de données d'application.
- Des modifications devront être apportées à my.cnf, y compris la définition du jeu de caractères, le classement et le passage de innodb_file_format à Barracuda
- Les instructions SQL CREATE peuvent devoir inclure:
ROW_FORMAT=DYNAMIC
- DYNAMIC est requis pour les index sur VARCHAR (192) et plus.
REMARQUE: le passage à Barracuda
de Antelope
peut nécessiter le redémarrage du service MySQL plusieurs fois. innodb_file_format_max
ne change pas avant le service MySQL a été redémarré à: innodb_file_format = barracuda
.
MySQL utilise l'ancien Antelope
format de fichier InnoDB. Barracuda
prend en charge les formats de ligne dynamiques, dont vous aurez besoin si vous ne voulez pas frapper les erreurs SQL pour créer des index et des clés après avoir basculé sur le jeu de caractères:utf8mb4
- # 1709 - La taille de la colonne d'index est trop grande. La taille de colonne maximale est de 767 octets.
- # 1071 - La clé spécifiée était trop longue; la longueur de clé maximale est de 767 octets
Le scénario suivant a été testé sur MySQL 5.6.17: Par défaut, MySQL est configuré comme ceci:
SHOW VARIABLES;
innodb_large_prefix = OFF
innodb_file_format = Antelope
Arrêtez votre service MySQL et ajoutez les options à votre my.cnf existant:
[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
Exemple d'instruction 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;
- Vous pouvez voir l'erreur # 1709 générée pour
INDEX contact_idx (contact)
si ROW_FORMAT=DYNAMIC
est supprimée de l'instruction CREATE.
REMARQUE: la modification de l'index pour limiter aux 128 premiers caractères sur contact
élimine la nécessité d'utiliser Barracuda avecROW_FORMAT=DYNAMIC
INDEX contact_idx (contact(128)),
Notez également: quand il est dit que la taille du champ est de VARCHAR(128)
128 octets. Vous pouvez utiliser 128 caractères de 4 octets ou 128 caractères de 1 octet.
Cette INSERT
instruction doit contenir le caractère «poo» de 4 octets sur la ligne 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💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩', '', '');
Vous pouvez voir la quantité d'espace utilisée par la last
colonne:
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
+--------------------+---------------------+
Dans votre adaptateur de base de données, vous souhaiterez peut-être définir le jeu de caractères et le classement pour votre connexion:
SET NAMES 'utf8mb4' COLLATE 'utf8mb4_unicode_ci'
En PHP, cela serait défini pour: \PDO::MYSQL_ATTR_INIT_COMMAND
Références: