Verwenden Sie am besten einen Zeichensatz für utf8mb4
die Sortierung utf8mb4_unicode_ci
.
Der Zeichensatz utf8
unterstützt nur eine kleine Anzahl von UTF-8-Codepunkten, etwa 6% der möglichen Zeichen. utf8
unterstützt nur das Basic Multilingual Plane (BMP). Es gibt 16 andere Flugzeuge. Jede Ebene enthält 65.536 Zeichen. utf8mb4
unterstützt alle 17 Flugzeuge.
MySQL schneidet 4-Byte-UTF-8-Zeichen ab, was zu beschädigten Daten führt.
Der utf8mb4
Zeichensatz wurde am 24.03.2010 in MySQL 5.5.3 eingeführt.
Einige der erforderlichen Änderungen zur Verwendung des neuen Zeichensatzes sind nicht trivial:
- Möglicherweise müssen Änderungen an Ihrem Anwendungsdatenbankadapter vorgenommen werden.
- An my.cnf müssen Änderungen vorgenommen werden, einschließlich des Festlegens des Zeichensatzes, der Sortierung und des Umschaltens von innodb_file_format auf Barracuda
- SQL CREATE-Anweisungen müssen möglicherweise Folgendes enthalten:
ROW_FORMAT=DYNAMIC
- DYNAMISCH ist für Indizes für VARCHAR (192) und höher erforderlich.
HINWEIS: Beim Umschalten auf Barracuda
von Antelope
muss der MySQL-Dienst möglicherweise mehrmals neu gestartet werden. innodb_file_format_max
ändert sich erst, nachdem der MySQL-Dienst neu gestartet wurde auf : innodb_file_format = barracuda
.
MySQL verwendet das alte Antelope
InnoDB-Dateiformat. Barracuda
unterstützt dynamische Zeilenformate, die Sie benötigen, wenn Sie die SQL-Fehler zum Erstellen von Indizes und Schlüsseln nach dem Wechsel zum Zeichensatz nicht feststellen möchten:utf8mb4
- # 1709 - Indexspaltengröße zu groß. Die maximale Spaltengröße beträgt 767 Byte.
- # 1071 - Der angegebene Schlüssel war zu lang. Die maximale Schlüssellänge beträgt 767 Byte
Das folgende Szenario wurde unter MySQL 5.6.17 getestet: Standardmäßig ist MySQL folgendermaßen konfiguriert:
SHOW VARIABLES;
innodb_large_prefix = OFF
innodb_file_format = Antelope
Beenden Sie Ihren MySQL-Dienst und fügen Sie die Optionen zu Ihrer vorhandenen my.cnf hinzu:
[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
Beispiel einer SQL CREATE-Anweisung:
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;
- Sie können den Fehler # 1709 sehen, der generiert wurde,
INDEX contact_idx (contact)
wenn ROW_FORMAT=DYNAMIC
er aus der CREATE-Anweisung entfernt wurde.
HINWEIS: Durch Ändern des Index auf maximal 128 Zeichen contact
entfällt die Verwendung von Barracuda mitROW_FORMAT=DYNAMIC
INDEX contact_idx (contact(128)),
Beachten Sie auch: Wenn die Größe des Felds angegeben ist VARCHAR(128)
, sind dies nicht 128 Byte. Sie können 128, 4-Byte-Zeichen oder 128, 1-Byte-Zeichen verwenden.
Diese INSERT
Anweisung sollte das 4-Byte-Zeichen 'poo' in der 2-Zeile enthalten:
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💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩', '', '');
Sie können den von der last
Spalte verwendeten Speicherplatz anzeigen:
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
+--------------------+---------------------+
In Ihrem Datenbankadapter möchten Sie möglicherweise den Zeichensatz und die Sortierung für Ihre Verbindung festlegen:
SET NAMES 'utf8mb4' COLLATE 'utf8mb4_unicode_ci'
In PHP wäre dies eingestellt für: \PDO::MYSQL_ATTR_INIT_COMMAND
Verweise: