查看“MySQL 字符集:Unicode 支持”的源代码
←
MySQL 字符集:Unicode 支持
跳到导航
跳到搜索
因为以下原因,您没有权限编辑本页:
您请求的操作仅限属于该用户组的用户执行:
用户
您可以查看和复制此页面的源代码。
[[category:MySQL]] == 关于 == Unicode 标准包括来自基本多语言平面(BMP)的字符和位于 BMP 之外的补充字符。【BMP,见[[ 关于:基本多语言平面(BMP)]]】 BMP 字符具有以下特征: # 它们的代码点值在 0 到 65535 之间(或 U+0000 和 U+FFFF)。 # 它们可以使用 8 位,16 位或 24 位(1 到 3 个字节)以可变长度编码进行编码。 # 它们可以使用 16 位(2 字节)以固定长度编码进行编码。 # 它们足以应付主要语言中的几乎所有字符。 补充字符位于 BMP 之外: # 它们的代码点值在 U+10000 和 U+10FFFF 之间)。 # Unicode 对补充字符的支持要求字符集的范围超出 BMP 字符,因此比 BMP 字符占用更多的空间(每个字符最多 4 个字节)。 * 【包括现在一些常用的'''表情字符''',如果使用不支持补充字符集的实现(如使用“utf8mb3”,而非“utf8mb4”)可能导致不能使用表情符号】 *: [[File:Unicode字符集中的Emoji表情字符.jpg|400px]] 根据 RFC 3629 实现了用于对 Unicode 数据进行编码的 UTF-8(具有 8 位单位的 Unicode 转换格式)方法,该方法描述了从一到四个字节的编码序列。 UTF-8 的思想是使用不同长度的字节序列对各种 Unicode 字符进行编码: # 基本的拉丁字母,数字和标点符号使用一个字节。 # 大多数欧洲和中东脚本字母均以 2 字节的顺序排列:扩展的拉丁字母(带有波浪号,马克龙,尖刻,重音和其他重音符号),西里尔字母,希腊语,亚美尼亚语,希伯来语,阿拉伯语,叙利亚语等。 # 韩文,中文和日文 表意字符使用 3 字节或 4 字节序列。 MySQL 支持以下 Unicode 字符集: # '''utf8mb4''':Unicode 字符集的 UTF-8 编码,每个字符使用 1-4 个字节。 # '''utf8mb3''':Unicode 字符集的 UTF-8 编码,每个字符使用一到三个字节。 # '''utf8''':utf8mb3的别名。 # '''ucs2''':Unicode 字符集的 UCS-2 编码,每个字符使用两个字节。 # '''utf16''':Unicode 字符集的 UTF-16 编码,每个字符使用两个或四个字节。类似于ucs2,但扩展了辅助字符。 # '''utf16le''':Unicode 字符集的 UTF-16LE 编码。像utf16,但是小端而不是大端。 # '''utf32''':Unicode 字符集的 UTF-32 编码,每个字符使用四个字节。 Unicode 字符集的一般特性 {| class="wikitable" ! Character Set !! Supported Characters !! 每个字符所需的存储量 |- | utf8mb3 , utf8 || BMP only || 1,2 或 3 个字节 |- | ucs2 || BMP only || 2 bytes |- | utf8mb4 || BMP 和补充 || 1,2、3 或 4 个字节 |- | utf16 || BMP 和补充 || 2 或 4 个字节 |- | utf16le || BMP 和补充 || 2 或 4 个字节 |- | utf32 || BMP 和补充 || 4 bytes |} * BMP 之外的字符将作为 REPLACEMENT CHARACTER 进行比较,并在转换为仅支持 BMP 字符(utf8mb3或ucs2)的 Unicode 字符集时转换为'?'。 * 如果您使用支持补充字符的字符集,并且比仅 BMP 的utf8mb3和ucs2字符集“宽”,则应用程序可能会出现不兼容的问题; * 大多数 Unicode 字符集都可以使用类似的排序规则集。例如,每个都有丹麦语排序规则,其名称为 utf8mb4_danish_ci,utf8mb3_danish_ci,utf8_danish_ci,ucs2_danish_ci,utf16_danish_ci 和 utf32_danish_ci。 *: (utf16le除外,它只有两个排序规则) * UCS-2,UTF-16 和 UTF-32 的 MySQL 实现以大端字节序列存储字符,并且在值的开头不使用“'''字节序列标记'''”('''BOM''')。其他数据库系统可能使用低位字节序或 BOM。在这种情况下,在这些系统和 MySQL 之间传输数据时将需要执行值的转换。 *: (UTF-16LE 的实现是小端的) * '''MySQL 对 UTF-8 值不使用 BOM。''' * 使用 Unicode 与服务器通信的 Client 端应用程序应相应地设置 Client 端字符集(例如,通过发出“SET NAMES 'utf8mb4'”语句)。某些字符集不能用作 Client 端字符集。 == utf8mb4 字符集(4 字节 UTF-8 Unicode 编码) == utfmb4字符集具有以下特征: # 支持 BMP 和补充字符。 # 每个多字节字符最多需要四个字节。 utf8mb4 与 utf8mb3(仅支持 BMP 字符,每个字符最多使用三个字节)对比: # 对于 BMP 字符,utf8mb4 和 utf8mb3 具有相同的存储特征:相同的代码值,相同的编码,相同的长度。 # 对于补充字符,utf8mb4 需要四个字节来存储它,而 utf8mb3 根本不能存储该字符。将 utf8mb3 列转换为 utf8mb4 时,您无需担心转换补充字符,因为将没有补充字符。 '''utf8mb4 是 utf8mb3 的超集''',因此对于诸如以下操作,结果具有字符集 utf8mb4 和排序规则 utf8mb4_col: <syntaxhighlight lang="xml"> SELECT CONCAT(utf8mb3_col, utf8mb4_col); </syntaxhighlight> 同样,WHERE 子句中的以下比较根据 utf8mb4_col 的排序规则起作用: <syntaxhighlight lang="xml"> SELECT * FROM utf8mb3_tbl, utf8mb4_tbl WHERE utf8mb3_tbl.utf8mb3_col = utf8mb4_tbl.utf8mb4_col; </syntaxhighlight> == utf8mb3(utf8)字符集(3 字节 UTF-8 Unicode 编码) == utf8mb3字符集具有以下特征: # 仅支持 BMP 字符(不支持补充字符) # 每个多字节字符最多需要三个字节。 * '''使用 UTF-8 数据但需要辅助字符支持的应用程序应使用 utf8mb4 而不是 utf8mb3。''' * utf8mb3 和 ucs2 中提供了完全相同的字符集。也就是说,它们具有相同的字符集。 * utf8 是 utf8mb3 的别名;字符限制是隐式的,而不是名称中的显式。 * utf8mb3 可用于“CHARACTER SET”子句,“utf8mb3_collation_substring”可用于“COLLATE”子句,其中“collation_substring”是:bin,czech_ci,danish_ci,esperanto_ci,estonian_ci等。例如: *: <syntaxhighlight lang="xml"> CREATE TABLE t (s1 CHAR(1) CHARACTER SET utf8mb3; SELECT * FROM t WHERE s1 COLLATE utf8mb3_general_ci = 'x'; DECLARE x VARCHAR(5) CHARACTER SET utf8mb3 COLLATE utf8mb3_danish_ci; SELECT CAST('a' AS CHAR CHARACTER SET utf8) COLLATE utf8_czech_ci; </syntaxhighlight> * MySQL 立即将语句中的 utf8mb3 实例转换为 utf8,因此在诸如“SHOW CREATE TABLE”或“SELECT CHARACTER_SET_NAME FROM INFORMATION_SCHEMA.COLUMNS”或“SELECT COLLATION_NAME FROM INFORMATION_SCHEMA.COLUMNS”的语句中,用户将看到名称 utf8 或 utf8_collation_substring。 * utf8mb3在除“CHARACTER SET”子句之外的上下文中也有效。例如: *: <syntaxhighlight lang="xml"> mysqld --character-set-server=utf8mb3 </syntaxhighlight> *: <syntaxhighlight lang="xml"> SET NAMES 'utf8mb3'; /* and other SET statements that have similar effect */ SELECT _utf8mb3 'a'; </syntaxhighlight> == ucs2 字符集(UCS-2 Unicode 编码) == 在 UCS-2 中,每个字符都由 2 字节 Unicode 代码表示,最高有效字节在前【大端存储】。例如:LATIN CAPITAL LETTER A的代码为0x0041,并存储为 2 字节序列:0x00 0x41。 ucs2 字符集具有以下特征: # '''仅支持 BMP 字符'''(不支持补充字符)。 # '''使用固定长度的 16 位编码''',每个字符需要两个字节。 == utf16 字符集(UTF-16 Unicode 编码)、utf16le 字符集 == utf16 字符集是支持补充字符的 ucs2字符集。 utf16 可以对补充字符进行编码: # 对于 BMP 字符,utf16 和 ucs2 具有相同的存储特征:相同的代码值,相同的编码,相同的长度。 # 对于补充字符,utf16 使用具有 32 位表示字符的特殊序列。这称为“代替”机制:对于大于“0xffff”的数字,请使用 10 位并将其添加到“0xd800”并将其放置在第一个 16 位字中,再使用 10 位并将其添加到“0xdc00”并将其放置在下一个 16 位字。因此,'''所有补充字符都需要 32 位''',其中前 16 位是“0xd800”和“0xdbff”之间的数字,而后 16 位是“0xdc00”和“0xdfff”之间的数字。 * utf16le:与utf16相同,但是是小端而不是大端存储。 == utf32 字符集(UTF-32 Unicode 编码) == utf32 字符集是固定长度的:'''对每个字符使用 32 位'''。 utf32 字符集具有以下特征: # utf32 的空间是 ucs2 的两倍,比 utf16的空间大,但是 utf32 与 ucs2 具有相同的优点,可以预测存储:'''utf32 的所需字节数等于字符数乘以 4'''。 # 此外,与utf16不同,在utf32中没有编码技巧,因此'''存储的值等于代码值'''。 #: 对此,乐意在给定 utf32 代码值的情况下确定 utf8mb4 值: #: <syntaxhighlight lang="xml"> /* Assume code value = 100cc LINEAR B WHEELED CHARIOT */ CREATE TABLE tmp (utf32_col CHAR(1) CHARACTER SET utf32, utf8mb4_col CHAR(1) CHARACTER SET utf8mb4); INSERT INTO tmp VALUES (0x000100cc,NULL); UPDATE tmp SET utf8mb4_col = utf32_col; SELECT HEX(utf32_col),HEX(utf8mb4_col) FROM tmp; </syntaxhighlight> * MySQL 非常宽容地添加未分配的 Unicode 字符或专用区域字符。实际上,对 utf32 仅进行一次有效性检查:'''任何代码值都不能大于“0x10ffff”'''。例如,这是非法的: *: <syntaxhighlight lang="xml"> INSERT INTO t (utf32_column) VALUES (0x110000); /* illegal */ </syntaxhighlight> == 在 3 字节和 4 字节 Unicode 字符集之间转换 == * 主要集中在 utf8mb3 和 utf8mb4 之间的转换,但是类似的原理适用于 ucs2 字符集和诸如 utf16 或 utf32 之类的字符集之间的转换。 utf8mb3 和 utf8mb4 字符集的区别如下: # utf8mb3 仅支持基本多语言平面(BMP)中的字符。 utf8mb4 还支持 BMP 之外的补充字符。 # utf8mb3 每个字符最多使用三个字节。 utf8mb4 每个字符最多使用四个字节。 * 从 utf8mb3 转换为 utf8mb4 的一个优点是,这使应用程序可以使用补充字符。一个缺点是这可能增加数据存储空间需求。 就 table 内容而言,从 utf8mb3 转换为 utf8mb4 不会出现问题: # 对于 BMP 字符,utf8mb4 和 utf8mb3 具有相同的存储特征:'''相同的代码值,相同的编码,相同的长度'''。 # 对于补充字符,utf8mb4 需要四个字节来存储它,而 utf8mb3 根本不能存储该字符。将 utf8mb3 列转换为 utf8mb4 时,您无需担心转换补充字符,因为将没有补充字符。 就 table 结构而言,这些是潜在的主要不兼容性: # 对于可变长度字符数据类型(VARCHAR 和 TEXT 类型),'''utf8mb4 列的字符允许的最大长度小于 utf8mb3 列的字符的最大允许长度'''。 # 对于所有字符数据类型(CHAR,VARCHAR和TEXT类型),'''utf8mb4 列的索引最大字符数少于 utf8mb3 列的索引数'''。 因此,要将 table 从 utf8mb3 转换为 utf8mb4,可能需要更改某些列或索引定义。在转换 MySQLtable 时请注意以下问题: # 检查 utf8mb3 列的所有定义,并确保它们不会超过存储引擎的最大长度。 # 检查 utf8mb 3列上的所有索引,并确保它们不会超过存储引擎的最大长度。有时,由于存储引擎的增强,最大值可能会更改。 如果满足上述条件,则必须减少定义的列或索引的长度,或者继续使用 utf8mb3 而不是 utf8mb4。 以下是一些可能需要进行结构更改的示例: # “TINYTEXT”列最多可容纳 255 个字节,因此最多可容纳 85 个 3 字节或 63 个 4 字节字符。 #: 假设您有一个使用 utf8mb3 的“TINYTEXT”列,但必须包含 63 个以上的字符。除非将数据类型更改为更长的类型,例如“TEXT”,否则不能将其转换为 utf8mb4。 #* 同样,如果要将“VARCHAR”较长的列从 utf8mb3 转换为 utf8mb4,则可能需要将其更改为较长的“TEXT”类型之一。 # 对于使用“COMPACT”或“REDUNDANT”行格式的 table,InnoDB的最大索引长度为 767 字节,因此对于 utf8mb3 或 utf8mb4 列,您最多可以分别索引 255 个或 191 个字符。如果当前有utf8mb3列的索引长于 191 个字符,则必须索引较少的字符。 #: 在使用“COMPACT”或“REDUNDANT”行格式的InnoDB table 中,这些列和索引定义是合法的: #: <syntaxhighlight lang="xml"> col1 VARCHAR(500) CHARACTER SET utf8, INDEX (col1(255)) </syntaxhighlight> #: 要改为使用utf8mb4,索引必须较小: #: <syntaxhighlight lang="xml"> col1 VARCHAR(500) CHARACTER SET utf8mb4, INDEX (col1(191)) </syntaxhighlight> #* 【对于使用“COMPRESSED”或“DYNAMIC”行格式的InnoDB table,您可以启用“innodb_large_prefix”选项以允许索引键前缀长于 767 字节(最多 3072 字节)。在这种情况下,启用“innodb_large_prefix”选项可使您分别为 utf8mb3 或 utf8mb4 列索引最多 1024 个或 768 个字符。(创建此类 table 还需要选项值“innodb_file_format=barracuda”和“innodb_file_per_table=true”)】 可以使用“ALTER TABLE”将 table 从 utf8mb3 转换为 utf8mb4。假设一个 table 具有以下定义: <syntaxhighlight lang="xml"> CREATE TABLE t1 ( col1 CHAR(10) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, col2 CHAR(10) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL ) CHARACTER SET utf8; </syntaxhighlight> 以下语句将 t1 转换为 utf8mb4: <syntaxhighlight lang="xml"> ALTER TABLE t1 DEFAULT CHARACTER SET utf8mb4, MODIFY col1 CHAR(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, MODIFY col2 CHAR(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL; </syntaxhighlight> 如果您已转换为 utf8mb4,utf16,utf16le 或 utf32,然后决定转换回 utf8mb3 或 ucs2 (例如,降级到旧版本的 MySQL),则适用以下注意事项: # utf8mb3 和 ucs2 数据应该没有问题。 # 服务器必须具有足够的最新性,以识别引用所要转换的字符集的定义。 # 对于引用 utf8mb4 字符集的对象定义,您可以在降级之前用 mysqldump 转储它们,编辑转储文件以将 utf8mb4 的实例更改为 utf8,然后在没有旧版本的服务器中重新加载文件,只要数据中没有 4 的字节字符。较旧的服务器将在转储文件对象定义中看到 utf8,并创建使用(3 字节)utf8字符集的新对象。
返回至“
MySQL 字符集:Unicode 支持
”。
导航菜单
个人工具
登录
命名空间
页面
讨论
大陆简体
已展开
已折叠
查看
阅读
查看源代码
查看历史
更多
已展开
已折叠
搜索
导航
首页
最近更改
随机页面
MediaWiki帮助
笔记
服务器
数据库
后端
前端
工具
《To do list》
日常
阅读
电影
摄影
其他
Software
Windows
WIKIOE
所有分类
所有页面
侧边栏
站点日志
工具
链入页面
相关更改
特殊页面
页面信息