MySQL 9.0 发行说明
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);