Karakter kümesini utf8mb4
harmanlama ile kullanmak en iyisidir utf8mb4_unicode_ci
.
Karakter seti, utf8
sadece az miktarda UTF-8 kod noktasını, olası karakterlerin yaklaşık% 6'sını destekler. utf8
sadece Temel Çok Dilli Düzlemi (BMP) destekler. 16 uçak daha var. Her uçak 65.536 karakter içeriyor. utf8mb4
17 uçağın hepsini destekler.
MySQL, 4 bayt UTF-8 karakterlerini keserek verilerin bozulmasına neden olur.
utf8mb4
Karakter kümesi 2010-03-24 tarihinde MySQL 5.5.3 tanıtıldı.
Yeni karakter setini kullanmak için gerekli değişikliklerden bazıları önemsiz değildir:
- Uygulama veritabanı bağdaştırıcınızda değişiklik yapılması gerekebilir.
- Karakter kümesinin ayarlanması, harmanlama ve innodb_file_format öğesinin Barracuda olarak değiştirilmesi de dahil olmak üzere my.cnf dosyasında değişiklikler yapılması gerekecektir.
- SQL CREATE deyimlerinin şunları içermesi gerekebilir:
ROW_FORMAT=DYNAMIC
- DİNAMİK, VARCHAR (192) ve daha büyük dizinler için gereklidir.
NOT: geçiş Barracuda
dan Antelope
kereden fazla MySQL hizmetini yeniden başlatmayı gerektirebilir. innodb_file_format_max
: MySQL servisi için çalıştıktan sonra dek değişmez innodb_file_format = barracuda
.
MySQL eski Antelope
InnoDB dosya biçimini kullanır . Barracuda
karakter kümesine geçtikten sonra dizinler ve anahtarlar oluşturmak için SQL hatalarına çarpmak istemiyorsanız ihtiyaç duyacağınız dinamik satır biçimlerini destekler:utf8mb4
- # 1709 - Dizin sütunu boyutu çok büyük. Maksimum sütun boyutu 767 bayttır.
- # 1071 - Belirtilen anahtar çok uzundu; maksimum anahtar uzunluğu 767 bayttır
Aşağıdaki senaryo MySQL 5.6.17 üzerinde test edilmiştir: Varsayılan olarak, MySQL şu şekilde yapılandırılmıştır:
SHOW VARIABLES;
innodb_large_prefix = OFF
innodb_file_format = Antelope
MySQL hizmetinizi durdurun ve mevcut my.cnf'nize seçenekleri ekleyin:
[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
Örnek SQL CREATE ifadesi:
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;
- Sen için oluşturulan hata # 1709 görebilirsiniz
INDEX contact_idx (contact)
eğer ROW_FORMAT=DYNAMIC
CREATE deyimi kaldırılır.
NOT: Dizinin ilk 128 karakterle sınırlandırılması, contact
Barracuda ile birlikte kullanılması gereksinimini ortadan kaldırırROW_FORMAT=DYNAMIC
INDEX contact_idx (contact(128)),
Ayrıca not: alanın boyutu söylendiğinde VARCHAR(128)
, bu 128 bayt değildir. 128, 4 bayt karakter veya 128, 1 bayt karakter kullanabilirsiniz.
Bu INSERT
ifade, 2 satırda 4 baytlık 'poo' karakterini içermelidir:
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💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩', '', '');
last
Sütun tarafından kullanılan alan miktarını görebilirsiniz :
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
+--------------------+---------------------+
Veritabanı bağdaştırıcınızda, bağlantınız için karakter kümesini ve harmanlamayı ayarlamak isteyebilirsiniz:
SET NAMES 'utf8mb4' COLLATE 'utf8mb4_unicode_ci'
PHP'de bu, aşağıdakiler için ayarlanır: \PDO::MYSQL_ATTR_INIT_COMMAND
Referanslar: