Cara terbaik adalah menggunakan set karakter utf8mb4
dengan collation utf8mb4_unicode_ci
.
Set karakter utf8
,, hanya mendukung sejumlah kecil poin kode UTF-8, sekitar 6% dari karakter yang mungkin. utf8
hanya mendukung Basic Multilingual Plane (BMP). Ada 16 pesawat lainnya. Setiap pesawat berisi 65.536 karakter. utf8mb4
mendukung semua 17 pesawat.
MySQL akan memotong karakter UTF-8 4 byte yang menghasilkan data rusak.
Set utf8mb4
karakter diperkenalkan di MySQL 5.5.3 pada 2010-03-24.
Beberapa perubahan yang diperlukan untuk menggunakan set karakter baru tidak sepele:
- Perubahan mungkin perlu dilakukan di adaptor basis data aplikasi Anda.
- Perubahan perlu dilakukan pada my.cnf, termasuk mengatur set karakter, susunan dan beralih innodb_file_format ke Barracuda
- Pernyataan SQL CREATE mungkin perlu mencakup:
ROW_FORMAT=DYNAMIC
- DYNAMIC diperlukan untuk indeks pada VARCHAR (192) dan lebih besar.
CATATAN: Beralih ke Barracuda
dari Antelope
, mungkin perlu memulai ulang layanan MySQL lebih dari sekali. innodb_file_format_max
tidak berubah sampai setelah layanan MySQL telah restart untuk: innodb_file_format = barracuda
.
MySQL menggunakan Antelope
format file InnoDB lama . Barracuda
mendukung format baris dinamis, yang akan Anda perlukan jika Anda tidak ingin menemukan kesalahan SQL untuk membuat indeks dan kunci setelah Anda beralih ke charset:utf8mb4
- # 1709 - Ukuran kolom indeks terlalu besar. Ukuran kolom maksimum adalah 767 byte.
- # 1071 - Kunci yang ditentukan terlalu panjang; panjang kunci maks adalah 767 byte
Skenario berikut telah diuji pada MySQL 5.6.17: Secara default, MySQL dikonfigurasi seperti ini:
SHOW VARIABLES;
innodb_large_prefix = OFF
innodb_file_format = Antelope
Hentikan layanan MySQL Anda dan tambahkan opsi ke my.cnf yang ada:
[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
Contoh pernyataan 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;
- Anda dapat melihat kesalahan # 1709 dihasilkan
INDEX contact_idx (contact)
jika ROW_FORMAT=DYNAMIC
dihapus dari pernyataan CREATE.
CATATAN: Mengubah indeks untuk membatasi ke 128 karakter pertama pada contact
menghilangkan persyaratan untuk menggunakan Barracuda denganROW_FORMAT=DYNAMIC
INDEX contact_idx (contact(128)),
Juga perhatikan: ketika dikatakan ukuran field adalah VARCHAR(128)
, itu bukan 128 byte. Anda dapat menggunakan karakter 128, 4 byte atau 128, 1 byte.
INSERT
Pernyataan ini harus berisi karakter 'kotoran' 4 byte di baris 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π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©π©', '', '');
Anda dapat melihat jumlah ruang yang digunakan oleh last
kolom:
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
+--------------------+---------------------+
Di adaptor database Anda, Anda mungkin ingin mengatur charset dan collation untuk koneksi Anda:
SET NAMES 'utf8mb4' COLLATE 'utf8mb4_unicode_ci'
Dalam PHP, ini akan ditetapkan untuk: \PDO::MYSQL_ATTR_INIT_COMMAND
Referensi: