MySQL 8.4 发行说明
utf16
字符集是 ucs2
字符集的扩展,支持对增补字符进行编码。
对于 BMP 字符,
utf16
和ucs2
具有相同的存储特性:相同的代码值、相同的编码、相同的长度。对于增补字符,
utf16
使用 32 位表示字符的特殊序列。这被称为““代理”机制:对于大于0xffff
的数字,取 10 位并将其添加到0xd800
,并将它们放在第一个 16 位字中,再取 10 位并将其添加到0xdc00
,并将它们放在下一个 16 位字中。因此,所有增补字符都需要 32 位,其中前 16 位是介于0xd800
和0xdbff
之间的数字,后 16 位是介于0xdc00
和0xdfff
之间的数字。示例请参见 Unicode 4.0 文档的第 15.5 节 代理区域。
由于 utf16
支持代理而 ucs2
不支持,因此有一个仅适用于 utf16
的有效性检查:不能在没有低位代理的情况下插入高位代理,反之亦然。例如
INSERT INTO t (ucs2_column) VALUES (0xd800); /* legal */
INSERT INTO t (utf16_column)VALUES (0xd800); /* illegal */
对于技术上有效但不是真正的 Unicode 字符(即 Unicode 认为是““未分配代码点”或““专用区”字符,甚至是像 0xffff
这样的““非法”字符)没有有效性检查。例如,由于 U+F8FF
是 Apple 徽标,因此以下是合法的
INSERT INTO t (utf16_column)VALUES (0xf8ff); /* legal */
不能期望此类字符对每个人都意味着相同的事物。
由于 MySQL 必须允许最坏的情况(一个字符需要四个字节),因此 utf16
列或索引的最大长度仅为 ucs2
列或索引最大长度的一半。例如,MEMORY
表索引键的最大长度为 3072 字节,因此以下语句创建的表包含 ucs2
和 utf16
列允许的最长索引:
CREATE TABLE tf (s1 VARCHAR(1536) CHARACTER SET ucs2) ENGINE=MEMORY;
CREATE INDEX i ON tf (s1);
CREATE TABLE tg (s1 VARCHAR(768) CHARACTER SET utf16) ENGINE=MEMORY;
CREATE INDEX i ON tg (s1);