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);