### 10.9.5 utf16 字符集（UTF-16 Unicode 编码）

[](<>)

这`utf16`字符集是`ucs2`具有启用补充字符编码的扩展名的字符集：

-   对于 BMP 字符，`utf16`和`ucs2`具有相同的存储特性：相同的代码值、相同的编码、相同的长度。

-   对于一个补充字符，`utf16`具有使用 32 位表示字符的特殊序列。这称为“代理”机制：对于大于`0xffff`，取 10 位并将它们添加到`0xd800`并将它们放在第一个 16 位字中，再取 10 位并将它们添加到`0xdc00`并将它们放在下一个 16 位字中。因此，所有补充字符都需要 32 位，其中前 16 位是介于`0xd800`和`0xdbff`, 最后 16 位是介于`0xdc00`和`0xdfff`.示例在部分[15.5 代理区域](http://www.unicode.org/versions/Unicode4.0.0/ch15.pdf)Unicode 4.0 文档。

    因为`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`列或索引。例如，最大长度`记忆`表索引键为 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);
```
