ที่ดีที่สุดคือการใช้ชุดตัวอักษรที่มีการเปรียบเทียบutf8mb4
utf8mb4_unicode_ci
ชุดอักขระutf8
รองรับเฉพาะจุดโค้ด UTF-8 เพียงเล็กน้อยเท่านั้นประมาณ 6% ของอักขระที่เป็นไปได้ utf8
รองรับ Basic Multilingual Plane (BMP) เท่านั้น มีเครื่องบินอีก 16 ลำ เครื่องบินแต่ละลำมี 65,536 ตัวอักษร utf8mb4
รองรับเครื่องบินทั้ง 17 ลำ
MySQL จะตัดทอนอักขระ UTF-8 ขนาด 4 ไบต์ทำให้ข้อมูลเสียหาย
utf8mb4
ชุดอักขระเป็นที่รู้จักใน MySQL 5.5.3 บน 2010-03-24
การเปลี่ยนแปลงที่จำเป็นบางอย่างเพื่อใช้ชุดอักขระใหม่นั้นไม่สำคัญ:
- อาจจำเป็นต้องทำการเปลี่ยนแปลงในอะแดปเตอร์ฐานข้อมูลแอปพลิเคชันของคุณ
- จะต้องทำการเปลี่ยนแปลงใน my.cnf รวมถึงการตั้งค่าชุดอักขระการเรียงและการสลับ innodb_file_format เป็น Barracuda
- คำสั่ง SQL CREATE อาจต้องมี:
ROW_FORMAT=DYNAMIC
- จำเป็นต้องใช้ DYNAMIC สำหรับดัชนีใน VARCHAR (192) ขึ้นไป
หมายเหตุ: การเปลี่ยนBarracuda
จากAntelope
อาจต้องเริ่มบริการ MySQL ใหม่มากกว่าหนึ่งครั้ง innodb_file_format_max
ไม่เปลี่ยนแปลงจนกว่าจะได้รับบริการ MySQL innodb_file_format = barracuda
ได้รับการเริ่มต้นใหม่ไปที่:
MySQL ใช้Antelope
รูปแบบไฟล์ InnoDB แบบเก่า Barracuda
สนับสนุนรูปแบบแถวแบบไดนามิกซึ่งคุณจะต้องถ้าคุณไม่ต้องการที่จะตีข้อผิดพลาด SQL สำหรับการสร้างดัชนีและคีย์หลังจากที่คุณเปลี่ยนเป็นชุดอักขระ:utf8mb4
- # 1709 - ขนาดคอลัมน์ดัชนีใหญ่เกินไป ขนาดคอลัมน์สูงสุดคือ 767 ไบต์
- # 1071 - รหัสที่ระบุยาวเกินไป ความยาวสูงสุดของคีย์คือ 767 ไบต์
สถานการณ์จำลองต่อไปนี้ได้รับการทดสอบบน MySQL 5.6.17: ตามค่าเริ่มต้น MySQL ได้รับการกำหนดค่าดังนี้:
SHOW VARIABLES;
innodb_large_prefix = OFF
innodb_file_format = Antelope
หยุดบริการ MySQL ของคุณและเพิ่มตัวเลือกใน my.cnf ที่มีอยู่ของคุณ:
[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
ตัวอย่างคำสั่ง 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;
- คุณสามารถดูข้อผิดพลาด # 1709 ที่สร้างขึ้น
INDEX contact_idx (contact)
หากROW_FORMAT=DYNAMIC
ถูกลบออกจากคำสั่ง CREATE
หมายเหตุ: การเปลี่ยนดัชนีเพื่อ จำกัด จำนวนอักขระสูงสุด 128 ตัวบนcontact
จะกำจัดข้อกำหนดสำหรับการใช้ Barracuda ด้วยROW_FORMAT=DYNAMIC
INDEX contact_idx (contact(128)),
หมายเหตุ: เมื่อมีข้อความระบุขนาดของเขตข้อมูลVARCHAR(128)
นั่นคือไม่ใช่ 128 ไบต์ คุณสามารถใช้มี 128, 4 ไบต์อักขระหรือ 128, 1 ไบต์อักขระ
INSERT
คำสั่งนี้ควรมีอักขระ 'poo' ขนาด 4 ไบต์ในแถวที่ 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💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩', '', '');
คุณสามารถดูจำนวนพื้นที่ที่last
คอลัมน์ใช้:
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
+--------------------+---------------------+
ในอะแดปเตอร์ฐานข้อมูลของคุณคุณอาจต้องการตั้ง charset และ collation สำหรับการเชื่อมต่อของคุณ:
SET NAMES 'utf8mb4' COLLATE 'utf8mb4_unicode_ci'
ใน PHP สิ่งนี้จะถูกตั้งค่าสำหรับ: \PDO::MYSQL_ATTR_INIT_COMMAND
อ้างอิง: