10.9.5 utf16 字符集(UTF-16 Unicode 编码)

utf16字符集是ucs2字符集,带有 extensions,可以对补充字符进行编码:

  • 对于 BMP 字符,utf16ucs2具有相同的存储 Feature:相同的代码值,相同的编码,相同的长度。

  • 对于补充字符,utf16具有使用 32 位 table 示字符的特殊序列。这称为“代理”机制:对于大于0xffff的数字,请使用 10 位并将其添加到0xd800并将其放置在第一个 16 位字中,再使用 10 位并将其添加到0xdc00并将其放置在下一个 16 位字。因此,所有补充字符都需要 32 位,其中前 16 位是0xd8000xdbff之间的数字,而后 16 位是0xdc000xdfff之间的数字。示例在 Unicode 4.0 文档的15 .5 代理区域部分中。

由于utf16支持代理,而ucs2不支持,因此仅在utf16中存在有效性检查:您不能在没有底部代理的情况下插入顶部代理,反之亦然。例如:

INSERT INTO t (ucs2_column) VALUES (0xd800); /* legal */
INSERT INTO t (utf16_column)VALUES (0xd800); /* illegal */

对于在技术上有效但不是 true 的 Unicode 的字符(即,Unicode 认为是“未分配的代码点”或“私有使用”的字符,甚至是“非法的”,如0xffff),没有有效性检查。例如,由于U+F8FF是 Apple 徽标,因此这是合法的:

INSERT INTO t (utf16_column)VALUES (0xf8ff); /* legal */

不能期望这样的字符对每个人都意味着相同的意思。

因为 MySQL 必须允许最坏的情况(一个字符需要四个字节),所以utf16列或索引的最大长度仅为ucs2列或索引的最大长度的一半。例如,MEMORYtable 索引键的最大长度为 3072 字节,因此这些语句创建的 table 具有ucs2utf16列允许的最长索引:

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