Tốt nhất là sử dụng bộ ký tự utf8mb4
với đối chiếu utf8mb4_unicode_ci
.
Bộ ký tự utf8
, chỉ hỗ trợ một lượng nhỏ điểm mã UTF-8, khoảng 6% ký tự có thể. utf8
chỉ hỗ trợ Mặt phẳng đa ngôn ngữ cơ bản (BMP). Có 16 máy bay khác. Mỗi mặt phẳng chứa 65.536 ký tự. utf8mb4
hỗ trợ tất cả 17 máy bay.
MySQL sẽ cắt bớt 4 ký tự UTF-8 byte dẫn đến dữ liệu bị hỏng.
Bộ utf8mb4
ký tự được giới thiệu trong MySQL 5.5.3 vào ngày 2010-03-24.
Một số thay đổi bắt buộc để sử dụng bộ ký tự mới không phải là nhỏ:
- Thay đổi có thể cần phải được thực hiện trong bộ điều hợp cơ sở dữ liệu ứng dụng của bạn.
- Các thay đổi sẽ cần được thực hiện đối với my.cnf, bao gồm thiết lập bộ ký tự, đối chiếu và chuyển đổi innodb_file_format sang Barracuda
- Các câu lệnh SQL CREATE có thể cần bao gồm:
ROW_FORMAT=DYNAMIC
- NĂNG ĐỘNG là cần thiết cho các chỉ mục trên VARCHAR (192) và lớn hơn.
LƯU Ý: Chuyển sang Barracuda
từ Antelope
, có thể yêu cầu khởi động lại dịch vụ MySQL nhiều lần. innodb_file_format_max
không thay đổi cho đến khi dịch vụ MySQL được khởi động lại thành : innodb_file_format = barracuda
.
MySQL sử dụng Antelope
định dạng tệp InnoDB cũ . Barracuda
hỗ trợ các định dạng hàng động mà bạn sẽ cần nếu bạn không muốn gặp các lỗi SQL để tạo chỉ mục và khóa sau khi bạn chuyển sang bộ ký tự:utf8mb4
- # 1709 - Kích thước cột chỉ mục quá lớn. Kích thước cột tối đa là 767 byte.
- # 1071 - Khóa được chỉ định quá dài; độ dài khóa tối đa là 767 byte
Kịch bản sau đây đã được thử nghiệm trên MySQL 5.6.17: Theo mặc định, MySQL được cấu hình như thế này:
SHOW VARIABLES;
innodb_large_prefix = OFF
innodb_file_format = Antelope
Dừng dịch vụ MySQL của bạn và thêm các tùy chọn vào my.cnf hiện tại của bạn:
[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
Ví dụ câu lệnh 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;
- Bạn có thể thấy lỗi # 1709 được tạo
INDEX contact_idx (contact)
nếu ROW_FORMAT=DYNAMIC
bị xóa khỏi câu lệnh CREATE.
LƯU Ý: Thay đổi chỉ mục để giới hạn ở 128 ký tự đầu tiên về contact
việc loại bỏ yêu cầu sử dụng Barracuda vớiROW_FORMAT=DYNAMIC
INDEX contact_idx (contact(128)),
Cũng lưu ý: khi nó nói kích thước của trường là VARCHAR(128)
, đó không phải là 128 byte. Bạn có thể sử dụng có 128, 4 ký tự byte hoặc ký tự 128, 1 byte.
Câu INSERT
lệnh này phải chứa ký tự 'poo' 4 byte trong hàng 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💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩', '', '');
Bạn có thể thấy lượng không gian được sử dụng bởi last
cột:
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
+--------------------+---------------------+
Trong bộ điều hợp cơ sở dữ liệu của bạn, bạn có thể muốn đặt bộ ký tự và đối chiếu cho kết nối của mình:
SET NAMES 'utf8mb4' COLLATE 'utf8mb4_unicode_ci'
Trong PHP, điều này sẽ được đặt cho: \PDO::MYSQL_ATTR_INIT_COMMAND
Người giới thiệu: