Es mejor usar el juego de caracteres utf8mb4con la intercalación utf8mb4_unicode_ci.
El conjunto de caracteres utf8, solo admite una pequeña cantidad de puntos de código UTF-8, aproximadamente el 6% de los posibles caracteres. utf8solo es compatible con el plano multilingüe básico (BMP). Hay otros 16 aviones. Cada plano contiene 65.536 caracteres. utf8mb4Soporta los 17 planos.
MySQL truncará los caracteres UTF-8 de 4 bytes, resultando en datos corruptos.
El utf8mb4conjunto de caracteres se introdujo en MySQL 5.5.3 el 2010-03-24.
Algunos de los cambios requeridos para usar el nuevo juego de caracteres no son triviales:
- Es posible que sea necesario realizar cambios en el adaptador de la base de datos de su aplicación.
- Será necesario realizar cambios en my.cnf, incluida la configuración del conjunto de caracteres, la clasificación y el cambio de innodb_file_format a Barracuda
- Las instrucciones SQL CREATE pueden necesitar incluir:
ROW_FORMAT=DYNAMIC
- DYNAMIC se requiere para índices en VARCHAR (192) y mayores.
NOTA: Cambiar a Barracudadesde Antelope, puede requerir reiniciar el servicio MySQL más de una vez. innodb_file_format_maxno cambia hasta después de que el servicio MySQL se ha reiniciado a: innodb_file_format = barracuda.
MySQL usa el antiguo Antelopeformato de archivo InnoDB. Barracudaadmite formatos de fila dinámicos, que necesitará si no desea obtener los errores de SQL para crear índices y claves después de cambiar al conjunto de caracteres:utf8mb4
- # 1709 - El tamaño de la columna de índice es demasiado grande. El tamaño máximo de columna es de 767 bytes.
- # 1071 - La clave especificada era demasiado larga; la longitud máxima de la clave es de 767 bytes
El siguiente escenario se ha probado en MySQL 5.6.17: de forma predeterminada, MySQL está configurado de esta manera:
SHOW VARIABLES;
innodb_large_prefix = OFF
innodb_file_format = Antelope
Detenga su servicio MySQL y agregue las opciones a su my.cnf existente:
[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
Ejemplo de sentencia 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;
- Puede ver el error # 1709 generado
INDEX contact_idx (contact)si ROW_FORMAT=DYNAMICse elimina de la instrucción CREATE.
NOTA: Cambiar el índice para limitar a los primeros 128 caracteres contactelimina el requisito de usar Barracuda conROW_FORMAT=DYNAMIC
INDEX contact_idx (contact(128)),
También tenga en cuenta: cuando dice que el tamaño del campo es VARCHAR(128), eso no es 128 bytes. Puede usar 128 caracteres de 4 bytes o 128 caracteres de 1 byte.
Esta INSERTdeclaración debe contener el carácter 'poo' de 4 bytes en la fila 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💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩', '', '');
Puede ver la cantidad de espacio utilizado por la lastcolumna:
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
+--------------------+---------------------+
En su adaptador de base de datos, puede configurar el juego de caracteres y la clasificación para su conexión:
SET NAMES 'utf8mb4' COLLATE 'utf8mb4_unicode_ci'
En PHP, esto se establecería para: \PDO::MYSQL_ATTR_INIT_COMMAND
Referencias