Es mejor usar el juego de caracteres utf8mb4
con 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. utf8
solo es compatible con el plano multilingüe básico (BMP). Hay otros 16 aviones. Cada plano contiene 65.536 caracteres. utf8mb4
Soporta los 17 planos.
MySQL truncará los caracteres UTF-8 de 4 bytes, resultando en datos corruptos.
El utf8mb4
conjunto 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 Barracuda
desde Antelope
, puede requerir reiniciar el servicio MySQL más de una vez. innodb_file_format_max
no cambia hasta después de que el servicio MySQL se ha reiniciado a: innodb_file_format = barracuda
.
MySQL usa el antiguo Antelope
formato de archivo InnoDB. Barracuda
admite 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=DYNAMIC
se elimina de la instrucción CREATE.
NOTA: Cambiar el índice para limitar a los primeros 128 caracteres contact
elimina 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 INSERT
declaració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 last
columna:
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