Documentation Home
MySQL 8.4 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 39.8Mb
PDF (A4) - 39.9Mb
Man Pages (TGZ) - 257.9Kb
Man Pages (Zip) - 364.9Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 Reference Manual  /  ...  /  The utf16 Character Set (UTF-16 Unicode Encoding)

12.9.5 UTF-16 字符集(UTF-16 Unicode 编码)

utf16 字符集是 ucs2 字符集的扩展,支持补充字符编码:

  • 对于 BMP 字符,utf16ucs2 都有相同的存储特性:同样的代码值、同样的编码、同样的长度。

  • 对于补充字符,utf16 使用 32 位特殊序列来表示该字符,这称为“代理”机制:对于大于 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 */

技术上来说,MySQL 对于所有有效的字符都没有验证,只有 Unicode 认为是未分配代码点、私用代码点或非法字符(如 0xffff)。例如,因为 U+F8FF 是苹果Logo,这是合法的:

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

这些字符不能被期望对每个人都有相同的含义。

因为 MySQL 必须允许最坏的情况(一个字符需要四个字节),所以 utf16 列或索引的最大长度只是一半的 ucs2 列或索引的最大长度。例如,MEMORY 表索引键的最大长度是 3072 字节,所以这些语句创建了最长允许的索引对 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);