utf16 字符集是带有扩展的 ucs2 字符集,使其能够对补充字符进行编码:The utf16 character set is the
ucs2 character set with an extension that
enables encoding of supplementary characters:
对于 BMP 字符,
utf16和ucs2的存储特性相同:相同的代码值、相同的编码、相同的长度。For a BMP character,utf16anducs2have identical storage characteristics: same code values, same encoding, same length.对于辅助字符,
utf16有一个使用 32 位表示该字符的特殊序列。这称为“代理”机制:对于大于0xffff的数字,取 10 位并加上0xd800,放入第一个 16 位字;再取另外 10 位并加上0xdc00,放入下一个 16 位字。因此,所有辅助字符都需要 32 位,其中前 16 位是介于0xd800和0xdbff之间的数字,后 16 位是介于0xdc00和0xdfff之间的数字。例子在 Unicode 4.0 文档的第 15.5 代理区 节中。For a supplementary character,utf16has a special sequence for representing the character using 32 bits. This is called the “surrogate” mechanism: For a number greater than0xffff, take 10 bits and add them to0xd800and put them in the first 16-bit word, take 10 more bits and add them to0xdc00and put them in the next 16-bit word. Consequently, all supplementary characters require 32 bits, where the first 16 bits are a number between0xd800and0xdbff, and the last 16 bits are a number between0xdc00and0xdfff. Examples are in Section 15.5 Surrogates Area of the Unicode 4.0 document.
因为 utf16 支持代理项,而 ucs2 不支持,所以有一个仅适用于 utf16 的有效性检查:不能在没有下位代理的情况下插入上位代理,反之亦然。例如:Because utf16 supports surrogates and
ucs2 does not, there is a validity check that
applies only in utf16: You cannot insert a
top surrogate without a bottom surrogate, or vice versa. For
example:
INSERT INTO t (ucs2_column) VALUES (0xd800); /* legal */ INSERT INTO t (utf16_column)VALUES (0xd800); /* illegal */
对于技术上有效但不是真正 Unicode 的字符(即 Unicode 认为是 “未分配的码点” 或 “私用” 字符,甚至是 “非法” 字符如 0xffff)没有有效性检查。例如,因为 U+F8FF 是苹果标志,这是合法的:There is no validity check for characters that are technically
valid but are not true Unicode (that is, characters that Unicode
considers to be “unassigned code points” or
“private use” characters or even
“illegals” like 0xffff). For
example, since U+F8FF is the Apple Logo, this
is legal:
INSERT INTO t (utf16_column)VALUES (0xf8ff); /* legal */
这样的字符不能指望对每个人都有相同的意义。Such characters cannot be expected to mean the same thing to everyone.
由于 MySQL 必须考虑最坏情况(一个字符可能需要四个字节),utf16 列或索引的最大长度仅为 ucs2 列或索引最大长度的一半。例如,MEMORY 表索引键的最大长度为 3072 字节,因此这些语句创建了具有 ucs2 和 utf16 列允许的最长索引的表:Because MySQL must allow for the worst case (that one character
requires four bytes) the maximum length of a
utf16 column or index is only half of the
maximum length for a ucs2 column or index.
For example, the maximum length of a MEMORY
table index key is 3072 bytes, so these statements create tables
with the longest permitted indexes for ucs2
and utf16 columns:
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);