企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
### 第10章:字符集支持 ** 目录** [ 10.1. 常规字符集和校对](#)[ 10.2. MySQL中的字符集和校对](#)[ 10.3. 确定默认字符集和校对](#)[ 10.3.1. 服务器字符集和校对](#)[ 10.3.2. 数据库字符集和校对](#)[ 10.3.3. 表字符集和校对](#)[ 10.3.4. 列字符集和校对](#)[ 10.3.5. 字符集和校对分配示例](#)[ 10.3.6. 连接字符集和校对](#)[ 10.3.7. 字符串文字字符集和校对](#)[ 10.3.8. 在SQL语句中使用COLLATE](#)[10.3.9. COLLATE子句优先](#)[10.3.10. BINARY操作符](#)[ 10.3.11. 校对确定较为复杂的一些特殊情况](#)[ 10.3.12. 校对必须适合字符集](#)[ 10.3.13. 校对效果的示例](#)[ 10.4. 字符集支持影响到的操作](#)[ 10.4.1. 结果字符串](#)[10.4.2. CONVERT()](#)[10.4.3. CAST()](#)[10.4.4. SHOW语句](#)[ 10.5. Unicode支持](#)[ 10.6. 用于元数据的UTF8](#)[ 10.7. 与其它DBMS的兼容性](#)[ 10.8. 新字符集配置文件格式](#)[ 10.9. 国家特有字符集](#)[ 10.10. MySQL支持的字符集和校对](#)[ 10.10.1. Unicode字符集](#)[ 10.10.2. 西欧字符集](#)[ 10.10.3. 中欧字符集](#)[ 10.10.4. 南欧与中东字符集](#)[ 10.10.5. 波罗的海字符集](#)[ 10.10.6. 西里尔字符集](#)[ 10.10.7. 亚洲字符集](#) 本章讨论以下主题: ·         什么是字符集和校对规则? ·         多级默认系统 ·         字符集语法 ·         相关函数和运算 ·         Unicode支持 ·         每个字符集和校对规则的含义 MySQL5.1中的字符集支持包括在MyISAM、MEMORY和InnoDB存储引擎中。 ### 10.1. 常规字符集和校对 *字符集*是一套符号和编码。*校对规则*是在字符集内用于比较字符的一套规则。让我们使用一个假想字符集的例子来区别清楚。 假设我们有一个字母表使用了四个字母:‘A’、‘B’、‘a’、‘b’。我们为每个字母赋予一个数值:‘A’=0,‘B’= 1,‘a’= 2,‘b’= 3。字母‘A’是一个符号,数字0是‘A’的编码,这四个字母和它们的编码组合在一起是一个**字符集**。 假设我们希望比较两个字符串的值:‘A’和‘B’。比较的最简单的方法是查找编码:‘A’为0,‘B’为1。因为0 小于1,我们可以说‘A’小于‘B’。我们做的仅仅是在我们的字符集上应用了一个 校对规则。校对规则是一套规则(在这种情况下仅仅是一套规则):“对编码进行比较。”我们称这种全部可能的规则中的最简单的 校对规则为一个*binary(二元)*校对规则。 但是,如果我们希望小写字母和大写字母是等价的,应该怎样?那么,我们将至少有两个规则:(1)把小写字母‘a’和‘b’视为与‘A’和‘B’等价;(2)然后比较编码。我们称这是一个大小写不敏感的 校对规则。比二元校对规则复杂一些。 在实际生活中,大多数字符集有许多字符:不仅仅是‘A’和‘B’,而是整个字母表,有时候有许多种字母表,或者一个东方的使用上千个字符的书写系统,还有许多特殊符号和标点符号。并且在实际生活中,大多数 校对规则有许多个规则:不仅仅是大小写不敏感,还包括重音符不敏感(“重音符” 是附属于一个字母的符号,象德语的‘Ö’符号)和多字节映射(例如,作为规则‘Ö’=‘OE’就是两个德语 校对规则的一种)。 MySQL5.1能够做这些事情: ·         使用多种字符集来存储字符串 ·         使用多种校对规则来比较字符串 ·         在同一台服务器、同一个数据库或甚至在同一个表中使用不同字符集或校对规则来混合字符串 ·         允许定义任何级别的字符集和校对规则 在这些方面,MySQL5.1不仅比MySQL4.1以前的版本灵活得多,而且比其它大多数数据库管理系统超前许多。但是,为了有效地使用这些功能,你需要了解哪些字符集和 校对规则是可用的,怎样改变默认值,以及它们怎样影响字符操作符和字符串函数的行为。 ### 10.2. MySQL中的字符集和校对 MySQL服务器能够支持多种字符集。可以使用SHOW CHARACTER SET语句列出可用的字符集: ~~~ mysql> SHOW CHARACTER SET; ~~~ ~~~ +----------+-----------------------------+---------------------+--------+ ~~~ ~~~ | Charset  | Description                 | Default collation   | Maxlen | ~~~ ~~~ +----------+-----------------------------+---------------------+--------+ ~~~ ~~~ | big5     | Big5 Traditional Chinese    | big5_chinese_ci     |      2 | ~~~ ~~~ | dec8     | DEC West European           | dec8_swedish_ci     |      1 | ~~~ ~~~ | cp850    | DOS West European           | cp850_general_ci    |      1 | ~~~ ~~~ | hp8      | HP West European            | hp8_english_ci      |      1 | ~~~ ~~~ | koi8r    | KOI8-R Relcom Russian       | koi8r_general_ci    |      1 | ~~~ ~~~ | latin1   | cp1252     West European    | latin1_swedish_ci   |      1 | ~~~ ~~~ | latin2   | ISO 8859-2 Central European | latin2_general_ci   |      1 | ~~~ ~~~ | swe7     | 7bit Swedish                | swe7_swedish_ci     |      1 | ~~~ ~~~ | ascii    | US ASCII                    | ascii_general_ci    |      1 | ~~~ ~~~ | ujis     | EUC-JP Japanese             | ujis_japanese_ci    |      3 | ~~~ ~~~ | sjis     | Shift-JIS Japanese          | sjis_japanese_ci    |      2 | ~~~ ~~~ | hebrew   | ISO 8859-8 Hebrew           | hebrew_general_ci   |      1 | ~~~ ~~~ | tis620   | TIS620 Thai                 | tis620_thai_ci      |      1 | ~~~ ~~~ | euckr    | EUC-KR Korean               | euckr_korean_ci     |      2 | ~~~ ~~~ | koi8u    | KOI8-U Ukrainian            | koi8u_general_ci    |      1 | ~~~ ~~~ | gb2312   | GB2312 Simplified Chinese   | gb2312_chinese_ci   |      2 | ~~~ ~~~ | greek    | ISO 8859-7 Greek            | greek_general_ci    |      1 | ~~~ ~~~ | cp1250   | Windows Central European    | cp1250_general_ci   |      1 | ~~~ ~~~ | gbk      | GBK Simplified Chinese      | gbk_chinese_ci      |      2 | ~~~ ~~~ | latin5   | ISO 8859-9 Turkish          | latin5_turkish_ci   |      1 | ~~~ ~~~ ... ~~~ (完整列表参见[10.10节,“MySQL支持的字符集和校对”](# "10.10. Character Sets and Collations That MySQL Supports")。) 任何一个给定的字符集至少有一个校对规则。它可能有几个校对规则。 要想列出一个字符集的校对规则,使用SHOW COLLATION语句。例如,要想查看latin1(“西欧ISO-8859-1”)字符集的 校对规则,使用下面的语句查找那些名字以latin1开头的 校对规则: ~~~ mysql> SHOW COLLATION LIKE 'latin1%'; ~~~ ~~~ +---------------------+---------+----+---------+----------+---------+ ~~~ ~~~ | Collation           | Charset | Id | Default | Compiled | Sortlen | ~~~ ~~~ +---------------------+---------+----+---------+----------+---------+ ~~~ ~~~ | latin1_german1_ci   | latin1  |  5 |         |          |       0 | ~~~ ~~~ | latin1_swedish_ci   | latin1  |  8 | Yes     | Yes      |       1 | ~~~ ~~~ | latin1_danish_ci    | latin1  | 15 |         |          |       0 | ~~~ ~~~ | latin1_german2_ci   | latin1  | 31 |         | Yes      |       2 | ~~~ ~~~ | latin1_bin          | latin1  | 47 |         | Yes      |       1 | ~~~ ~~~ | latin1_general_ci   | latin1  | 48 |         |          |       0 | ~~~ ~~~ | latin1_general_cs   | latin1  | 49 |         |          |       0 | ~~~ ~~~ | latin1_spanish_ci   | latin1  | 94 |         |          |       0 | ~~~ ~~~ +---------------------+---------+----+---------+----------+---------+ ~~~ latin1校对规则有下面的含义: <table border="1" cellpadding="0" id="table1"><tr><td> <p><strong><span>校对规则</span></strong></p></td> <td> <p><strong><span>含义</span></strong></p></td> </tr><tr><td> <p> <span>latin1_german1_ci</span></p></td> <td> <p>德国<span>DIN-1</span></p></td> </tr><tr><td> <p> <span>latin1_swedish_ci</span></p></td> <td> <p>瑞典<span>/</span>芬兰</p></td> </tr><tr><td> <p> <span>latin1_danish_ci</span></p></td> <td> <p>丹麦<span>/</span>挪威</p></td> </tr><tr><td> <p> <span>latin1_german2_ci</span></p></td> <td> <p>德国<span> DIN-2</span></p></td> </tr><tr><td> <p> <span>latin1_bin</span></p></td> <td> <p>符合<span>latin1</span>编码的二进制</p></td> </tr><tr><td> <p> <span>latin1_general_ci</span></p></td> <td> <p>多种语言<span>(</span>西欧<span>)</span></p></td> </tr><tr><td> <p> <span>latin1_general_cs</span></p></td> <td> <p>多种语言<span>(</span>西欧<span>ISO),</span>大小写敏感</p></td> </tr><tr><td> <p> <span>latin1_spanish_ci</span></p></td> <td> <p>现代西班牙</p></td> </tr></table> 校对规则一般有这些特征: ·         两个不同的字符集不能有相同的校对规则。 ·         每个字符集有一个*默认校对规则*。例如,latin1默认校对规则是latin1_swedish_ci。 ·         存在校对规则命名约定:它们以其相关的字符集名开始,通常包括一个语言名,并且以_ci(大小写不敏感)、_cs(大小写敏感)或_bin(二元)结束。 ### 10.3. 确定默认字符集和校对 [ 10.3.1. 服务器字符集和校对](#)[ 10.3.2. 数据库字符集和校对](#)[ 10.3.3. 表字符集和校对](#)[ 10.3.4. 列字符集和校对](#)[ 10.3.5. 字符集和校对分配示例](#)[ 10.3.6. 连接字符集和校对](#)[ 10.3.7. 字符串文字字符集和校对](#)[ 10.3.8. 在SQL语句中使用COLLATE](#)[10.3.9. COLLATE子句优先](#)[10.3.10. BINARY操作符](#)[ 10.3.11. 校对确定较为复杂的一些特殊情况](#)[ 10.3.12. 校对必须适合字符集](#)[ 10.3.13. 校对效果的示例](#) 字符集和校对规则有4个级别的默认设置:服务器级、数据库级、表级和连接级。以下描述可能显得复杂,但是在实际应用中可以发现使用多种级别会使结果自然而明显。 ### 10.3.1. 服务器字符集和校对 MySQL服务器有一个服务器字符集和一个服务器校对规则,它们均不能设置为空。 MySQL按照如下方法确定服务器字符集和服务器校对规则: ·         当服务器启动时根据有效的选项设置 ·         根据运行时的设定值 在服务器级别,确定方法很简单。当启动**mysqld**时,根据使用的初始选项设置来确定服务器字符集和 校对规则。可以使用--default-character-set设置字符集,并且可以在字符集后面为 校对规则添加--default-collation。如果没有指定一个字符集,那就与--default-character-set=latin1相同。如果你仅指定了一个字符集(例如,latin1),但是没有指定一个 校对规则,那就与--default-charset=latin1 --default-collation=latin1_swedish_ci相同,因为latin1_swedish_ci是latin1的默认校对规则。因此,以下三个命令有相同的效果: shell> **mysqld** shell> **mysqld --default-character-set=latin1** shell> **mysqld --default-character-set=latin1 \**            **--default-collation=latin1_swedish_ci** 更改设定值的一个方法是通过重新编译。如果希望在从源程序构建时更改默认服务器字符集和校对规则,使用:--with-charset和--with-collation作为**configure**的参量。例如: ~~~ shell> ./configure --with-charset=latin1 ~~~ 或者: shell> **./configure --with-charset=latin1 \**            ** --with-collation=latin1_german1_ci** **mysqld**和**configure**都验证字符集/校对规则组合是否有效。如果无效,每个程序都显示一个错误信息,然后终止。 当前的服务器字符集和校对规则可以用作character_set_server和collation_server系统变量的值。在运行时能够改变这些变量的值。 ### 10.3.2. 数据库字符集和校对 每一个数据库有一个数据库字符集和一个数据库校对规则,它不能够为空。CREATE DATABASE和ALTER DATABASE语句有一个可选的子句来指定数据库字符集和校对规则: ~~~ CREATE DATABASE db_name ~~~ ~~~     [[DEFAULT] CHARACTER SET charset_name] ~~~ ~~~     [[DEFAULT] COLLATE collation_name] ~~~ ~~~   ~~~ ~~~ ALTER DATABASE db_name ~~~ ~~~     [[DEFAULT] CHARACTER SET charset_name] ~~~ ~~~     [[DEFAULT] COLLATE collation_name] ~~~ 例如: ~~~ CREATE DATABASE db_name ~~~ ~~~     DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci; ~~~ MySQL这样选择数据库字符集和数据库校对规则: ·         如果指定了CHARACTER SET X和COLLATE Y,那么采用字符集*X*和校对规则*Y*。 ·         如果指定了CHARACTER SET X而没有指定COLLATE Y,那么采用CHARACTER SET X和CHARACTER SET X的默认校对规则。 ·         否则,采用服务器字符集和服务器校对规则。 MySQL的CREATE DATABASE ... DEFAULT CHARACTER SET ...语法与标准SQL的CREATE SCHEMA ... CHARACTER SET ...语法类似。因此,可以在同一个MySQL服务器上创建使用不同字符集和 校对规则的数据库。 如果在CREATE TABLE语句中没有指定表字符集和校对规则,则使用数据库字符集和校对规则作为默认值。它们没有其它目的。 默认数据库的字符集和校对规则可以用作character_set_database和 collation_database系统变量。无论何时默认数据库更改了,服务器都设置这两个变量的值。如果没有 默认数据库,这两个变量与相应的服务器级别的变量(character_set_server和collation_server)具有相同的值。 ### 10.3.3. 表字符集和校对 每一个表有一个表字符集和一个校对规则,它不能为空。为指定表字符集和校对规则,CREATE TABLE和ALTER TABLE语句有一个可选的子句: ~~~ CREATE TABLE tbl_name (column_list) ~~~ ~~~     [DEFAULT CHARACTER SET charset_name [COLLATE collation_name]] ~~~ ~~~   ~~~ ~~~ ALTER TABLE tbl_name ~~~ ~~~     [DEFAULT CHARACTER SET charset_name] [COLLATE collation_name] ~~~ 例如: ~~~ CREATE TABLE t1 ( ... ) ~~~ DEFAULT CHARACTER SET latin1 COLLATE latin1_danish_ci; MySQL按照下面的方式选择表字符集和 校对规则: ·         如果指定了CHARACTER SET X和COLLATE Y,那么采用CHARACTER SET X和COLLATE Y。 ·         如果指定了CHARACTER SET X而没有指定COLLATE Y,那么采用CHARACTER SET X和CHARACTER SET X的默认校对规则。 ·         否则,采用服务器字符集和服务器校对规则。 如果在列定义中没有指定列字符集和校对规则,则默认使用表字符集和校对规则。表字符集和校对规则是MySQL的扩展;在标准SQL中没有。 ### 10.3.4. 列字符集和校对 每一个“字符”列(即,CHAR、VARCHAR或TEXT类型的列)有一个列字符集和一个列 校对规则,它不能为空。列定义语法有一个可选子句来指定列字符集和校对规则: ~~~ col_name {CHAR | VARCHAR | TEXT} (col_length) ~~~ ~~~     [CHARACTER SET charset_name [COLLATE collation_name]] ~~~ 例如: CREATE TABLE Table1 (     column1 VARCHAR(5) CHARACTER SET latin1 COLLATE latin1_german1_ci ); MySQL按照下面的方式选择列字符集和校对规则: ·         如果指定了CHARACTER SET X和COLLATE Y,那么采用CHARACTER SET X和COLLATE Y。 ·         如果指定了CHARACTER SET X而没有指定COLLATE Y,那么采用CHARACTER SET X和CHARACTER SET X的默认校对规则。 ·         否则,采用表字符集和服务器校对规则。 CHARACTER SET和COLLATE子句是标准的SQL。 ### 10.3.5. 字符集和校对分配示例 以下例子显示了MySQL怎样确定默认字符集和校对规则。 **示例1:表和列定义** ~~~ CREATE TABLE t1 ~~~ ~~~ ( ~~~ ~~~     c1 CHAR(10) CHARACTER SET latin1 COLLATE latin1_german1_ci ~~~ ~~~ ) DEFAULT CHARACTER SET latin2 COLLATE latin2_bin; ~~~ 在这里我们有一个列使用latin1字符集和latin1_german1_ci校对规则。是显式的定义,因此简单明了。需要注意的是,在一个latin2表中存储一个latin1列不会存在问题。 **示例2:表和列定义** ~~~ CREATE TABLE t1 ~~~ ~~~ ( ~~~ ~~~     c1 CHAR(10) CHARACTER SET latin1 ~~~ ~~~ ) DEFAULT CHARACTER SET latin1 COLLATE latin1_danish_ci; ~~~ 这次我们有一个列使用latin1字符集和一个默认校对规则。尽管它显得自然,默认校对规则却不是表级。相反,因为latin1的默认校对规则总是latin1_swedish_ci,列c1有一个校对规则latin1_swedish_ci(而不是latin1_danish_ci)。 **示例3:表和列定义** ~~~ CREATE TABLE t1 ~~~ ~~~ ( ~~~ ~~~     c1 CHAR(10) ~~~ ~~~ ) DEFAULT CHARACTER SET latin1 COLLATE latin1_danish_ci; ~~~ 我们有一个列使用一个默认字符集和一个默认校对规则。在这种情况下,MySQL查找表级别来确定列字符集和 校对规则。因此,列c1的字符集是latin1,它的 校对规则是latin1_danish_ci。 **示例4:数据库、表和列定义** ~~~ CREATE DATABASE d1 ~~~ ~~~     DEFAULT CHARACTER SET latin2 COLLATE latin2_czech_ci; ~~~ ~~~ USE d1; ~~~ ~~~ CREATE TABLE t1 ~~~ ~~~ ( ~~~ ~~~     c1 CHAR(10) ~~~ ~~~ ); ~~~ 我们创建了一个没有指定字符集和校对规则的列。我们也没有指定表级字符集和校对规则。在这种情况下,MySQL查找数据库级的相关设置。(数据库的设置变为表的设置,其后变为列的设置。)因此,列c1的字符集为是latin2,它的 校对规则是latin2_czech_ci。 ### 10.3.6. 连接字符集和校对 一些字符集和校对规则系统变量与客户端和服务器的交互有关。在前面的章节中已经提到过部分内容: ·         服务器字符集和校对规则可以用作character_set_server和collation_server变量的值。 ·         默认数据库的字符集和校对规则可以用作character_set_database和collation_database变量的值。 在客户端和服务器的连接处理中也涉及了字符集和校对规则变量。每一个客户端有一个连接相关的字符集和校对规则变量。 考虑什么是一个“连接”:它是连接服务器时所作的事情。客户端发送SQL语句,例如查询,通过连接发送到服务器。服务器通过连接发送响应给客户端,例如结果集。对于客户端连接,这样会导致一些关于连接的字符集和 校对规则的问题,这些问题均能够通过系统变量来解决: ·         当查询离开客户端后,在查询中使用哪种字符集? 服务器使用character_set_client变量作为客户端发送的查询中使用的字符集。 ·         服务器接收到查询后应该转换为哪种字符集? 转换时,服务器使用character_set_connection和collation_connection系统变量。它将客户端发送的查询从character_set_client系统变量转换到character_set_connection(除非字符串文字具有象_latin1或_utf8的引介词)。collation_connection对比较文字字符串是重要的。对于列值的字符串比较,它不重要,因为列具有更高的 校对规则优先级。 ·         服务器发送结果集或返回错误信息到客户端之前应该转换为哪种字符集? character_set_results变量指示服务器返回查询结果到客户端使用的字符集。包括结果数据,例如列值和结果元数据(如列名)。 你能够调整这些变量的设置,或可以依赖默认值(这样,你可以跳过本章)。 有两个语句影响连接字符集: ~~~ SET NAMES 'charset_name' ~~~ ~~~ SET CHARACTER SET charset_name ~~~ SET NAMES显示客户端发送的SQL语句中使用什么字符集。因此,SET NAMES 'cp1251'语句告诉服务器“将来从这个客户端传来的信息采用字符集cp1251”。它还为服务器发送回客户端的结果指定了字符集。(例如,如果你使用一个SELECT语句,它表示列值使用了什么字符集。) SET NAMES '*x*'语句与这三个语句等价: ~~~ mysql> SET character_set_client = x; ~~~ ~~~ mysql> SET character_set_results = x; ~~~ ~~~ mysql> SET character_set_connection = x; ~~~ 将x设置为character_set_connection也就设置了collation_connection是x的默认校对规则。 SET CHARACTER SET语句是类似的,但是为 默认数据库设置连接字符集和校对规则。SET CHARACTER SET x语句与这三个语句等价: ~~~ mysql> SET character_set_client = x; ~~~ ~~~ mysql> SET character_set_results = x; ~~~ ~~~ mysql> SET collation_connection = @@collation_database; ~~~ 当一个客户端连接时,它向服务器发送希望使用的字符集名称。服务器为那个字符集设置character_set_client、character_set_results和 character_set_connection变量。(实际上,服务器为使用该字符集执行一个SET NAMES操作。) 对于**mysql**客户端,如果你希望使用与默认字符集不同的字符集,不需要每次启动时执行SET NAMES语句。可以在**mysql**语句行中或者选项文件中添加一个--default-character-set选项设置。例如,你每次运行**mysql**时,以下的选项文件设置把三个字符集变量修改为koi8r: [mysql] default-character-set=koi8r 例如:假设column1定义为CHAR(5) CHARACTER SET latin2。如果没有设定SET NAMES或SET CHARACTER SET,那么对于SELECT column1 FROM t,当连接后,服务器使用客户端指定的字符集返回列column1的所有值。另一方面,如果你设定SET NAMES 'latin1'或SET CHARACTER SET latin1,那么发送结果之前,服务器转换latin2值到latin1。转换可能会丢失那些不属于两种字符集的字符。 如果不希望服务器执行任何转换,设置character_set_results为NULL: ~~~ mysql> SET character_set_results = NULL; ~~~ ### 10.3.7. 字符串文字字符集和校对 每一字符串字符文字有一个字符集和一个校对规则,它不能为空。 一个字符串文字可能有一个可选的字符集引介词和COLLATE子句: ~~~ [_charset_name]'string' [COLLATE collation_name] ~~~ 例如: ~~~ SELECT 'string'; ~~~ ~~~ SELECT _latin1'string'; ~~~ ~~~ SELECT _latin1'string' COLLATE latin1_danish_ci; ~~~ 对于简单的语句SELECT '*string*',字符串使用由character_set_connection和collation_connection系统变量定义的字符集和 校对规则。 _*charset_name*表达式正式称做一个*引介词*。它告诉解析程序,“后面将要出现的字符串使用字符集X。”因为以前人们对此感到困惑,我们强调引介词不导致任何转换; 它仅是一个符号,不改变字符串的值。引介词在标准十六进制字母和数字十六进制符号(x'*literal*'和 0x*nnnn*)中是合法的,以及?(当在一个编程语言接口中使用预处理的语句时进行参数替换)。 例如: ~~~ SELECT _latin1 x'AABBCC'; ~~~ ~~~ SELECT _latin1 0xAABBCC; ~~~ ~~~ SELECT _latin1 ?; ~~~ MySQL这样确定一个文字字符集和校对规则: ·         如果指定了CHARACTER SET X和COLLATE Y,那么使用CHARACTER SET X和COLLATE Y。 ·         如果指定了CHARACTER SET X而没有指定COLLATE Y,那么使用CHARACTER SET X和CHARACTER SET X的默认校对规则。 ·         否则,使用通过character_set_connection和 collation_connection系统变量给出的字符集和 校对规则。 例如: ·         使用latin1字符集和latin1_german1_ci校对规则的字符串: ~~~ ·                SELECT _latin1'Müller' COLLATE latin1_german1_ci; ~~~ ·         使用latin1字符集和其默认校对规则的字符串(即,latin1_swedish_ci): ~~~ ·                SELECT _latin1'Müller'; ~~~ ·         使用连接默认字符集和校对规则的字符串: ~~~ ·                SELECT 'Müller'; ~~~ 字符集引介词和COLLATE子句是根据标准SQL规范实现的。 ### 10.3.8. 在SQL语句中使用COLLATE - 使用COLLATE子句,能够为一个比较覆盖任何默认校对规则。COLLATE可以用于多种SQL语句中。下面是一些例子: ·         使用ORDER BY: ~~~ ·                SELECT k ~~~ ~~~ ·                FROM t1 ~~~ ~~~ ·                ORDER BY k COLLATE latin1_german2_ci; ~~~ ·         使用AS: ~~~ ·                SELECT k COLLATE latin1_german2_ci AS k1 ~~~ ~~~ ·                FROM t1 ~~~ ~~~ ·                ORDER BY k1; ~~~ ·         使用GROUP BY: ~~~ ·                SELECT k ~~~ ~~~ ·                FROM t1 ~~~ ~~~ ·                GROUP BY k COLLATE latin1_german2_ci; ~~~ ·         使用聚合函数: ~~~ ·                SELECT MAX(k COLLATE latin1_german2_ci) ~~~ ~~~ ·                FROM t1; ~~~ ·         使用DISTINCT: ~~~ ·                SELECT DISTINCT k COLLATE latin1_german2_ci ~~~ ~~~ ·                FROM t1; ~~~ ·         使用WHERE: ~~~ ·                     SELECT * ~~~ ~~~ ·                     FROM t1 ~~~ ~~~ ·                     WHERE _latin1 'Müller' COLLATE latin1_german2_ci = k; ~~~ ~~~ ·                     SELECT * ~~~ ~~~ ·                     FROM t1 ~~~ ~~~ ·                     WHERE k LIKE _latin1 'Müller' COLLATE latin1_german2_ci; ~~~ ·         使用HAVING: ~~~ ·                SELECT k ~~~ ~~~ ·                FROM t1 ~~~ ~~~ ·                GROUP BY k ~~~ ~~~ ·                HAVING k = _latin1 'Müller' COLLATE latin1_german2_ci; ~~~ ### 10.3.9. COLLATE子句优先 COLLATE子句有较高的优先级(高于||),因此下面两个表达式是等价的: ~~~ x || y COLLATE z ~~~ ~~~ x || (y COLLATE z) ~~~ ### 10.3.10. BINARY操作符 BINARY操作符是COLLATE子句的一个速记符。BINARY '*x*'等价与'*x*' COLLATE *y*,这里*y*是字符集'*x*'二元 校对规则的名字。每一个字符集有一个二元校对规则。例如,latin1字符集的二元 校对规则是latin1_bin,因此,如果列a是字符集latin1,以下两个语句有相同效果: ~~~ SELECT * FROM t1 ORDER BY BINARY a; ~~~ ~~~ SELECT * FROM t1 ORDER BY a COLLATE latin1_bin; ~~~ ### 10.3.11. 校对确定较为复杂的一些特殊情况 在绝大多数查询中,MySQL使用哪种校对规则进行比较是很显然的。例如,在下列情况中,校对规则明显的是“列x的列校对规则”: ~~~ SELECT x FROM T ORDER BY x; ~~~ ~~~ SELECT x FROM T WHERE x = x; ~~~ ~~~ SELECT DISTINCT x FROM T; ~~~ 但是,当涉及多个操作数时,可能不明确。例如: ~~~ SELECT x FROM T WHERE x = 'Y'; ~~~ 这个查询应该使用列x的 校对规则,还是字符串文字'Y'的 校对规则? 标准化SQL使用“可压缩性”规则解决这种问题。基本上,这个意思是:既然x和'Y'都有 校对规则,哪个校对规则优先?这可能比较难解决,但是以下规则适合大多数情况: ·         一个外在的COLLATE子句可压缩性是0(根本不能压缩。) ·         使用不同校对规则的两个字符串连接的可压缩性是1。 ·         列校对规则的可压缩性是2。 ·         “系统常数”(如USER()或VERSION()函数返回的字符串)可压缩性是3。 ·         文字规则的可压缩性是4。 ·         NULL或从NULL派生的表达式的可压缩性是 5。 上述可压缩性值是MySQL5.1当前所用的。 这样上述规则可以模糊解决: ·         使用最低的可压缩性值的校对规则。 ·         如果两侧有相同的可压缩性,那么如果校对规则不同则发生错误。 例如: <table border="1" cellpadding="0" id="table2"><tr><td> <p> <span>column1 = 'A'</span></p></td> <td> <p>使用<span>column1</span>的校对规则</p></td> </tr><tr><td> <p> <span>column1 = 'A' COLLATE x</span></p></td> <td> <p>使用<span>'A'</span>的校对规则</p></td> </tr><tr><td> <p> <span>column1 COLLATE x = 'A' COLLATE y</span></p></td> <td> <p>错误</p></td> </tr></table> 使用COERCIBILITY()函数确定一个字符串表达式的可压缩性: ~~~ mysql> SELECT COERCIBILITY('A' COLLATE latin1_swedish_ci); ~~~ ~~~         -> 0 ~~~ ~~~ mysql> SELECT COERCIBILITY(VERSION()); ~~~ ~~~         -> 3 ~~~ ~~~ mysql> SELECT COERCIBILITY('A'); ~~~ ~~~         -> 4 ~~~ 见[12.9.3节,“信息函数”](# "12.9.3. Information Functions")。 没有系统常数或可忽略的压缩性。函数如USER()的可压缩性是2而不是3,文字的可压缩性是3而不是4。 ### 10.3.12. 校对必须适合字符集 请注意每个字符集有一个或多个校对规则,并且每个校对规则只能属于一个字符集。因此,以下语句会产生一个错误信息,因为校对规则latin2_bin对于字符集latin1非法: mysql> **SELECT _latin1 'x' COLLATE latin2_bin;** ERROR 1251: COLLATION 'latin2_bin' is not valid for CHARACTER SET 'latin1' ### 10.3.13. 校对效果的示例 假设表T中的列X有这些latin1列值: Muffler Müller MX Systems MySQL 假设使用下面的语句获取列值: SELECT X FROM T ORDER BY X COLLATE *collation_name*; 使用不同校对规则的列值结果排序见下表: <table border="1" cellpadding="0" id="table3"><tr><td> <p> <span>latin1_swedish_ci</span></p></td> <td> <p> <span>latin1_german1_ci</span></p></td> <td> <p> <span>latin1_german2_ci</span></p></td> </tr><tr><td> <p><span>Muffler</span></p></td> <td> <p><span>Muffler</span></p></td> <td> <p><span>M</span>ü<span>ller</span></p></td> </tr><tr><td> <p><span>MX</span>系统</p></td> <td> <p><span>M</span>ü<span>ller</span></p></td> <td> <p><span>Muffler</span></p></td> </tr><tr><td> <p><span>M</span>ü<span>ller</span></p></td> <td> <p><span>MX</span>系统</p></td> <td> <p><span>MX</span>系统</p></td> </tr><tr><td> <p><span>MySQL</span></p></td> <td> <p><span>MySQL</span></p></td> <td> <p><span>MySQL</span></p></td> </tr></table> 本表显示了我们在ORDER BY字句中使用不同所校对规则的效果的示例。在本例中导致不同排序的字符是上面带有两个圆点的U(ü),它在德语中发音为"U-umlaut"。 ·         第一列显示的是使用瑞典/芬兰校对规则的SELECT语句的结果,它被称作U-umlaut使用Y排序。 ·         第二列显示的是使用德语DIN-1校对规则的SELECT语句的结果,它被称作U-umlaut使用U排序。 ·         第三列显示的是使用德语DIN-2校对规则的SELECT语句的结果,它被称作U-umlaut使用UE排序。 ### 10.4. 字符集支持影响到的操作 [ 10.4.1. 结果字符串](#)[10.4.2. CONVERT()](#)[10.4.3. CAST()](#)[10.4.4. SHOW语句](#) 本节讨论在MySQL5.1中考虑到字符集信息的操作。 ### 10.4.1. 结果字符串 MySQL中有许多操作符和函数可以返回字符串。本节回答这个问题:返回的字符串使用什么字符集和 校对规则? 对于简单的函数,即接收字符串输入然后返回一个字符串结果作为输出的函数,输出的字符集和校对规则与原始输入的相同。例如,UPPER(*X*)返回一个字符串,其字符和 校对规则与*X*相同。类似的函数还有INSTR()、LCASE()、LOWER()、LTRIM()、MID()、REPEAT()、REPLACE()、REVERSE()、RIGHT()、RPAD()、RTRIM()、SOUNDEX()、SUBSTRING()、TRIM()、UCASE()和UPPER()。(还需要注意:REPLACE()函数不同于其它函数,它总是忽略输入字符串的 校对规则,并且进行大小写不敏感的比较。) 对于合并多个字符串输入并且返回单个字符串输出的运算,应用标准SQL“聚合规则”: ·         如果存在显式的校对规则*X*,那么使用*X*。 ·         如果存在显式的校对规则*X和Y*,那么产生一个错误。 ·         否则,如果全部校对规则是*X*,那么使用*X*。 ·         其它情况,结果没有校对规则。 例如,使用CASE ... WHEN a THEN b WHEN b THEN c COLLATE *X* END。结果校对规则是X。对于CASE、UNION、||、CONCAT()、ELT()、GREATEST()、IF()和LEAST()情况相同。 对于转换为字符数据的运算,从运算得到的结果字符串的字符集和校对规则由character_set_connection和collation_connection系统变量定义。这适用于CAST()、CHAR()、CONV()、FORMAT()、HEX()和SPACE()函数。 ### 10.4.2. CONVERT() CONVERT()提供一个在不同字符集之间转换数据的方法。语法是: ~~~ CONVERT(expr USING transcoding_name) ~~~ 在 MySQL中,转换代码名与相应的字符集名相同。 例子: ~~~ SELECT CONVERT(_latin1'Müller' USING utf8); ~~~ ~~~ INSERT INTO utf8table (utf8column) ~~~ ~~~     SELECT CONVERT(latin1field USING utf8) FROM latin1table; ~~~ CONVERT(... USING ...)根据标准SQL规范实施。 在传统SQL模式中,如果你转换一个“0”日期字符串到日期类型,CONVERT()函数返回NULL。在MySQL5.1中还产生一条警告。 ### 10.4.3. CAST() 你也可以使用CAST()函数将一个字符串转换到一个不同的字符集。语法是: CAST(*character_string* AS * character_data_type* CHARACTER SET *charset_name*) 例如: SELECT CAST(_latin1'test' AS CHAR CHARACTER SET utf8); 如果使用CAST()时没有指定CHARACTER SET,结果字符集和校对规则通过character_set_connection 和 collation_connection系统变量定义。如果用CAST()并带有CHARACTER SET X选项,那么结果字符集和校对规则是X和其 默认的校对规则。 你可能不能在CAST()中使用COLLATE子句,但是你可以在外部使用它。也就是说,不是CAST(... COLLATE ...),而是CAST(...) COLLATE ...。 例如: SELECT CAST(_latin1'test' AS CHAR CHARACTER SET utf8) COLLATE utf8_bin; 在传统SQL模式中,如果你转换一个“0”日期字符串到日期类型,CAST()函数返回NULL。在MySQL5.1中还产生一条警告。 ### 10.4.4. SHOW语句 一些SHOW语句提供额外的字符集信息。这些语句包括SHOW CHARACTER SET、SHOW COLLATION、SHOW CREATE DATABASE、SHOW CREATE TABLE和SHOW COLUMNS。 SHOW CHARACTER SET命令显示全部可用的字符集。它带有一个可选的LIKE子句来指示匹配哪些字符集名。例如: mysql> **SHOW CHARACTER SET LIKE 'latin%';** +---------+-----------------------------+-------------------+--------+ | Charset | Description                 | Default collation | Maxlen | +---------+-----------------------------+-------------------+--------+ | latin1  | cp1252 West European        | latin1_swedish_ci |      1 | | latin2  | ISO 8859-2 Central European | latin2_general_ci |      1 | | latin5  | ISO 8859-9 Turkish          | latin5_turkish_ci |      1 | | latin7  | ISO 8859-13 Baltic          | latin7_general_ci |      1 | +---------+-----------------------------+-------------------+--------+ 见[13.5.4.1节,“SHOW CHARACTER SET语法”](# "13.5.4.1. SHOW CHARACTER SET Syntax")。 SHOW COLLATION语句的输出包括全部可用的字符集。它带有一个可选的LIKE子句来指示匹配哪些 校对规则名。例如: ~~~ mysql> SHOW COLLATION LIKE 'latin1%'; ~~~ ~~~ +-------------------+---------+----+---------+----------+---------+ ~~~ ~~~ | Collation         | Charset | Id | Default | Compiled | Sortlen | ~~~ ~~~ +-------------------+---------+----+---------+----------+---------+ ~~~ ~~~ | latin1_german1_ci | latin1  |  5 |         |          |       0 | ~~~ ~~~ | latin1_swedish_ci | latin1  |  8 | Yes     | Yes      |       0 | ~~~ ~~~ | latin1_danish_ci  | latin1  | 15 |         |          |       0 | ~~~ ~~~ | latin1_german2_ci | latin1  | 31 |         | Yes      |       2 | ~~~ ~~~ | latin1_bin        | latin1  | 47 |         | Yes      |       0 | ~~~ ~~~ | latin1_general_ci | latin1  | 48 |         |          |       0 | ~~~ ~~~ | latin1_general_cs | latin1  | 49 |         |          |       0 | ~~~ ~~~ | latin1_spanish_ci | latin1  | 94 |         |          |       0 | ~~~ ~~~ +-------------------+---------+----+---------+----------+---------+ ~~~ 见[13.5.4.2节,“SHOW COLLATION语法”](# "13.5.4.2. SHOW COLLATION Syntax")。 SHOW CREATE DATABASE语句显示创建给定数据库的CREATE DATABASE语句。结果包括全部数据库选项。支持DEFAULT CHARACTER SET和COLLATE。全部数据库选项存储在命名为db.Opt的文本文件中,该文件能够在数据库目录中找到。 ~~~ mysql> SHOW CREATE DATABASE test; ~~~ ~~~ +----------+-----------------------------------------------------------------+ ~~~ ~~~ | Database | Create Database                                                 | ~~~ ~~~ +----------+-----------------------------------------------------------------+ ~~~ ~~~ | test     | CREATE DATABASE `test` /*!40100 DEFAULT CHARACTER SET latin1 */ | ~~~ ~~~ +----------+-----------------------------------------------------------------+ ~~~ 见[13.5.4.4节,“SHOW CREATE DATABASE语法”](# "13.5.4.4. SHOW CREATE DATABASE Syntax") SHOW CREATE TABLE与SHOW CREATE DATABASE相似,但是显示创建给定数据库的CREATE TABLE语句。列定义显示任何字符集规格,并且表选项包括字符集信息。 见[13.5.4.5节,“SHOW CREATE TABLE语法”](# "13.5.4.5. SHOW CREATE TABLE Syntax") 当以SHOW FULL COLUMNS调用时,SHOW COLUMNS语句显示表中列的校对规则。具有CHAR、VARCHAR或TEXT数据类型的列有非NULL的 校对规则。数值列和其它非字符类型的列有NULL校对规则。例如: mysql> **SHOW FULL COLUMNS FROM person\G** *************************** 1. row ***************************      Field: id       Type: smallint(5) unsigned  Collation: NULL       Null: NO        Key: PRI    Default: NULL      Extra: auto_increment Privileges: select,insert,update,references    Comment: *************************** 2. row ***************************      Field: name       Type: char(60)  Collation: latin1_swedish_ci       Null: NO        Key:    Default:      Extra: Privileges: select,insert,update,references    Comment: 字符集不是显示的部分。(字符集名隐含在校对规则名中。) 见[13.5.4.3节,“SHOW COLUMNS语法”](# "13.5.4.3. SHOW COLUMNS Syntax")。 ### 10.5. Unicode支持 MySQL 5.1支持两种字符集以保存Unicode数据: ·         ucs2,UCS-2 Unicode字符集。 ·         utf8,Unicode字符集的UTF8编码。 在UCS-2(二进制Unicode表示法)中,每一个字符用一个双字节的Unicode编码来表示的,第一个字节表示重要的意义。例如:"LATIN CAPITAL LETTER A"的Unicode编码是0x0041,它按顺序存储为两个字节:0x00 0x41。"CYRILLIC SMALL LETTER YERU"(Unicode 0x044B)顺序存储为两个字节:0x04 0x4B。对于Unicode字符和它们的编码,请参见[Unicode 主页](http://www.unicode.org/)。 当前,UCS-2还不能够用作为客户端字符集,这意味着SET NAMES 'ucs2'不起作用。 UTF8字符集(转换Unicode表示)是存储Unicode数据的一种可选方法。它根据 RFC 3629执行。UTF8字符集的思想是不同Unicode字符采用变长字节序列编码: ·         基本拉丁字母、数字和标点符号使用一个字节。 ·         大多数的欧洲和中东手写字母适合两个字节序列:扩展的拉丁字母(包括发音符号、长音符号、重音符号、低音符号和其它音符)、西里尔字母、希腊语、亚美尼亚语、希伯来语、阿拉伯语、叙利亚语和其它语言。 ·         韩语、中文和日本象形文字使用三个字节序列。 RFC 3629说明了采用一到四个字节的编码序列。当前,MySQLUTF8不支持四个字节。(UTF8编码的旧标准是由RFC 2279给出,它描述了从一到六个字节的UTF8编码序列。RFC 3629补充了作废的RFC 2279;因此,不再使用5个字节和6个字节的编码序列。) **提示**:使用UTF8时为了节省空间,使用VARCHAR而不要用CHAR。否则,MySQL必须为一个CHAR(10) CHARACTER SET utf8列预备30个字节,因为这是可能的最大长度。 ### 10.6. 用于元数据的UTF8 *元数据*是“关于数据的数据”。描述数据库的任何数据—作为数据库内容的对立面—是元数据。因此,列名、数据库名、用户名、版本名以及从SHOW语句得到的结果中的大部分字符串是元数据。还包括INFORMATION_SCHEMA数据库中的表中的内容,因为定义的那些表存储关于数据库对象的信息。 元数据表述必须满足这些需求: ·         全部元数据必须在同一字符集内。否则,对INFORM一个TION_SCHEMA数据库中的表执行的SHOW命令和SELECT查询不能正常工作,因为这些运算结果中的同一列的不同行将会使用不同的字符集。 ·         元数据必须包括所有语言的所有字符。否则,用户将不能够使用它们自己的语言来命名列和表。 为了满足这两个需求,MySQL使用Unicode字符集存储元数据,即UTF8。如果你从不使用重音字符,这不会导致任何破坏。但如果你使用重音字符,应该注意的是元数据是用UTF8存储。 这意味着,USER()、CURRENT_USER()、DATABASE()和VERSION()函数的返回值被 默认设置为UTF8字符集,这与同义函数如SESSION_USER()和SYSTEM_USER()的结果相同。 服务器将character_set_system系统变量设置为元数据字符集的名: ~~~ mysql> SHOW VARIABLES LIKE 'character_set_system'; ~~~ ~~~ +----------------------+-------+ ~~~ ~~~ | Variable_name        | Value | ~~~ ~~~ +----------------------+-------+ ~~~ ~~~ | character_set_system | utf8  | ~~~ ~~~ +----------------------+-------+ ~~~ 存储元数据使用Unicode并不意味着列头和DESCRIBE函数的结果默认在character_set_system字符集中。当你使用SELECT column1 FROM t语句时,名字为column1的列从服务器返回客户端并使用由SET NAMES语句确定的字符集。更明确地说,使用的字符集是由character_set_results系统变量的值确定的。如果这个系统变量设置为NULL,不执行字符转换,服务器使用最初的字符集(字符集由character_set_system系统变量设置)返回元数据。 如果你希望服务器不使用UTF8字符集返回元数据结果,那么使用SET NAMES语句强制服务器执行字符集转换(见[10.3.6节,“连接字符集和校对”](# "10.3.6. Connection Character Sets and Collations")),或者在客户端执行转换。在客户端执行转换效率较高,但这种选项并不能使用于全部客户端。 如果你正在一个语句中使用(例如)USER()函数进行比较或赋值,不要担心。MySQL为你执行一些原子转换。 ~~~ SELECT * FROM Table1 WHERE USER() = latin1_column; ~~~ 这是可以的,因为在比较之前latin1_column列的内容会自动转换到UTF8。 ~~~ INSERT INTO Table1 (latin1_column) SELECT USER(); ~~~ 这是可以的,因为赋值之前USER()函数返回的内容自动转换为latin1。至今,自动转换没有全部实施,但是以后的版本中应该工作正常。 尽管自动转换不属于SQL标准,SQL标准化文档中说每一个字符集是(根据支持的字符)Unicode的“子集”。因此,一个知名的原则是,“适用超集的字符集能够应用于其子集”,我们相信Unicode的 校对规则能够应用于非Unicode字符串的比较。 **注释**:在MySQL5.1中,errmsg.txt文件全部使用UTF8。客户端字符集的转换是自动进行的,如同元数据。 ### 10.7. 与其它DBMS的兼容性 对于MaxDB兼容性,下面两个语句是相同的: ~~~ CREATE TABLE t1 (f1 CHAR(n) UNICODE); CREATE TABLE t1 (f1 CHAR(n) CHARACTER SET ucs2); ~~~ ### 10.8. 新字符集配置文件格式 字符集配置存储在XML文件中,一个字符集对应一个文件。 ### 10.9. 国家特有字符集 ANSI SQL定义了NCHAR或者NATIONAL CHAR作为一个方法来指示CHAR类型的列应该使用某些预定义的字符集。MySQL5.1使用utf8作为预定义的字符集。例如,这些列类型声明是等价的: ~~~ CHAR(10) CHARACTER SET utf8 ~~~ ~~~ NATIONAL CHARACTER(10) ~~~ ~~~ NCHAR(10) ~~~ 下面同样: ~~~ VARCHAR(10) CHARACTER SET utf8 ~~~ ~~~ NATIONAL VARCHAR(10) ~~~ ~~~ NCHAR VARCHAR(10) ~~~ ~~~ NATIONAL CHARACTER VARYING(10) ~~~ ~~~ NATIONAL CHAR VARYING(10) ~~~ 你能够使用N'*literal*'来创建一个使用国家特有字符集的字符串。这两个语句是等价的: ~~~ SELECT N'some text'; ~~~ ~~~ SELECT _utf8'some text'; ~~~ 关于MySQL从4.1以前的版本到5.1版本字符集升级的信息,请参见*MySQL4.1参考手册*。 ### 10.10. MySQL支持的字符集和校对 [ 10.10.1. Unicode字符集](#)[ 10.10.2. 西欧字符集](#)[ 10.10.3. 中欧字符集](#)[ 10.10.4. 南欧与中东字符集](#)[ 10.10.5. 波罗的海字符集](#)[ 10.10.6. 西里尔字符集](#)[ 10.10.7. 亚洲字符集](#) MySQL支持30多种字符集的70多种 校对规则。字符集和它们的默认校对规则可以通过SHOW CHARACTER SET语句显示: ~~~ mysql> SHOW CHARACTER SET; +----------+-----------------------------+---------------------+ | Charset | Description | Default collation | +----------+-----------------------------+---------------------+ | big5 | Big5 Traditional Chinese | big5_chinese_ci | | dec8 | DEC West European | dec8_swedish_ci | | cp850 | DOS West European | cp850_general_ci | | hp8 | HP West European | hp8_english_ci | | koi8r | KOI8-R Relcom Russian | koi8r_general_ci | | latin1 | cp1252 West European | latin1_swedish_ci | | latin2 | ISO 8859-2 Central European | latin2_general_ci | | swe7 | 7bit Swedish | swe7_swedish_ci | | ascii | US ASCII | ascii_general_ci | | ujis | EUC-JP Japanese | ujis_japanese_ci | | sjis | Shift-JIS Japanese | sjis_japanese_ci | | hebrew | ISO 8859-8 Hebrew | hebrew_general_ci | | tis620 | TIS620 Thai | tis620_thai_ci | | euckr | EUC-KR Korean | euckr_korean_ci | | koi8u | KOI8-U Ukrainian | koi8u_general_ci | | gb2312 | GB2312 Simplified Chinese | gb2312_chinese_ci | | greek | ISO 8859-7 Greek | greek_general_ci | | cp1250 | Windows Central European | cp1250_general_ci | | gbk | GBK Simplified Chinese | gbk_chinese_ci | | latin5 | ISO 8859-9 Turkish | latin5_turkish_ci | | armscii8 | ARMSCII-8 Armenian | armscii8_general_ci | | utf8 | UTF-8 Unicode | utf8_general_ci | | ucs2 | UCS-2 Unicode | ucs2_general_ci | | cp866 | DOS Russian | cp866_general_ci | | keybcs2 | DOS Kamenicky Czech-Slovak | keybcs2_general_ci | | macce | Mac Central European | macce_general_ci | | macroman | Mac West European | macroman_general_ci | | cp852 | DOS Central European | cp852_general_ci | | latin7 | ISO 8859-13 Baltic | latin7_general_ci | | cp1251 | Windows Cyrillic | cp1251_general_ci | | cp1256 | Windows Arabic | cp1256_general_ci | | cp1257 | Windows Baltic | cp1257_general_ci | | binary | Binary pseudo charset | binary | | geostd8 | GEOSTD8 Georgian | geostd8_general_ci | | cp932 | SJIS for Windows Japanese | cp932_japanese_ci | | eucjpms | UJIS for Windows Japanese | eucjpms_japanese_ci | +----------+-----------------------------+---------------------+ ~~~ ### 10.10.1. Unicode字符集 MySQL有两种Unicode字符集。你能够使用这些字符集保存大约650种语言的文本。 ·         ucs2 (UCS-2 Unicode)校对规则: - ~~~ mysql> SHOW COLLATION LIKE 'ucs2%'; +--------------------+---------+-----+---------+----------+---------+ | Collation | Charset | Id | Default | Compiled | Sortlen | +--------------------+---------+-----+---------+----------+---------+ | ucs2_general_ci | ucs2 | 35 | Yes | Yes | 1 | | ucs2_bin | ucs2 | 90 | | Yes | 1 | | ucs2_unicode_ci | ucs2 | 128 | | Yes | 8 | | ucs2_icelandic_ci | ucs2 | 129 | | Yes | 8 | | ucs2_latvian_ci | ucs2 | 130 | | Yes | 8 | | ucs2_romanian_ci | ucs2 | 131 | | Yes | 8 | | ucs2_slovenian_ci | ucs2 | 132 | | Yes | 8 | | ucs2_polish_ci | ucs2 | 133 | | Yes | 8 | | ucs2_estonian_ci | ucs2 | 134 | | Yes | 8 | | ucs2_spanish_ci | ucs2 | 135 | | Yes | 8 | | ucs2_swedish_ci | ucs2 | 136 | | Yes | 8 | | ucs2_turkish_ci | ucs2 | 137 | | Yes | 8 | | ucs2_czech_ci | ucs2 | 138 | | Yes | 8 | | ucs2_danish_ci | ucs2 | 139 | | Yes | 8 | | ucs2_lithuanian_ci | ucs2 | 140 | | Yes | 8 | | ucs2_slovak_ci | ucs2 | 141 | | Yes | 8 | | ucs2_spanish2_ci | ucs2 | 142 | | Yes | 8 | | ucs2_roman_ci | ucs2 | 143 | | Yes | 8 | | ucs2_persian_ci | ucs2 | 144 | | Yes | 8 | | ucs2_esperanto_ci | ucs2 | 145 | | Yes | 8 | +--------------------+---------+-----+---------+----------+---------+ ~~~ - utf8 (UTF-8 Unicode)校对规则: ~~~ mysql> SHOW COLLATION LIKE 'utf8%'; +--------------------+---------+-----+---------+----------+---------+ | Collation | Charset | Id | Default | Compiled | Sortlen | +--------------------+---------+-----+---------+----------+---------+ | utf8_general_ci | utf8 | 33 | Yes | Yes | 1 | | utf8_bin | utf8 | 83 | | Yes | 1 | | utf8_unicode_ci | utf8 | 192 | | Yes | 8 | | utf8_icelandic_ci | utf8 | 193 | | Yes | 8 | | utf8_latvian_ci | utf8 | 194 | | Yes | 8 | | utf8_romanian_ci | utf8 | 195 | | Yes | 8 | | utf8_slovenian_ci | utf8 | 196 | | Yes | 8 | | utf8_polish_ci | utf8 | 197 | | Yes | 8 | | utf8_estonian_ci | utf8 | 198 | | Yes | 8 | | utf8_spanish_ci | utf8 | 199 | | Yes | 8 | | utf8_swedish_ci | utf8 | 200 | | Yes | 8 | | utf8_turkish_ci | utf8 | 201 | | Yes | 8 | | utf8_czech_ci | utf8 | 202 | | Yes | 8 | | utf8_danish_ci | utf8 | 203 | | Yes | 8 | | utf8_lithuanian_ci | utf8 | 204 | | Yes | 8 | | utf8_slovak_ci | utf8 | 205 | | Yes | 8 | | utf8_spanish2_ci | utf8 | 206 | | Yes | 8 | | utf8_roman_ci | utf8 | 207 | | Yes | 8 | | utf8_persian_ci | utf8 | 208 | | Yes | 8 | | utf8_esperanto_ci | utf8 | 209 | | Yes | 8 | +--------------------+---------+-----+---------+----------+---------+ ~~~ utf8_unicode_ci校对规则是根据Unicode校对规则算法(UCA)执行的, 校对规则描述见 [ http://www.unicode.org/reports/tr10/](http://www.unicode.org/reports/tr10/)。此校对规则使用UCA 4.0.0版本砝码键:[http://www.unicode.org/Public/UC一个/4.0.0/一个llkeys-4.0.0.txt](http://www.unicode.org/Public/UCA/4.0.0/allkeys-4.0.0.txt)。(以下讨论使用utf8_unicode_ci,但同样适合ucs2_unicode_ci。) 当前,utf8_unicode_ci校对规则仅部分支持Unicode校对规则算法。一些字符还是不能支持。并且,不能完全支持组合的记号。这主要影响越南和俄罗斯的一些少数民族语言,如:Udmurt 、Tatar、Bashkir和Mari。 utf8_unicode_ci的最主要的特色是支持扩展,即当把一个字母看作与其它字母组合相等时。例如,在德语和一些其它语言中‘ß’等于‘ss’。 utf8_general_ci是一个遗留的 校对规则,不支持扩展。它仅能够在字符之间进行逐个比较。这意味着utf8_general_ci校对规则进行的比较速度很快,但是与使用utf8_unicode_ci的 校对规则相比,比较正确性较差)。 例如,使用utf8_general_ci和utf8_unicode_ci两种 校对规则下面的比较相等: ~~~ Ä = A ~~~ ~~~ Ö = O ~~~ ~~~ Ü = U ~~~ 两种校对规则之间的区别是,对于utf8_general_ci下面的等式成立: ~~~ ß = s ~~~ 但是,对于utf8_unicode_ci下面等式成立: ~~~ ß = ss ~~~ 对于一种语言仅当使用utf8_unicode_ci排序做的不好时,才执行与具体语言相关的utf8字符集 校对规则。例如,对于德语和法语,utf8_unicode_ci工作的很好,因此不再需要为这两种语言创建特殊的utf8校对规则。 utf8_general_ci也适用与德语和法语,除了‘ß’等于‘s’,而不是‘ss’之外。如果你的应用能够接受这些,那么应该使用utf8_general_ci,因为它速度快。否则,使用utf8_unicode_ci,因为它比较准确。 utf8_swedish_ci,与其它语言相关的utf8的校对规则相似,来源于utf8_unicode_ci,使用额外的语言规则。例如,在瑞典语中,以下的关系式成立,它在德语和法语中不成立: ~~~ Ü = Y < Ö ~~~ utf8_spanish_ci和utf8_spanish2_ci校对规则分别适用于现代和古典西班牙语。在两种 校对规则中,ñ’(n-发音符)是‘n’和‘o’之间的间隔字母。另外,对于古典西班牙语,‘ch’是‘c’和d之间的间隔字母,并且‘ll’是‘l’和‘m’之间的间隔字母。 ### 10.10.2. 西欧字符集 西欧字符集覆盖大多数西欧语言,如法语、西班牙语、加泰罗尼亚语、巴斯克人语、葡萄牙语、意大利语、阿而巴尼亚语、荷兰语、德语、丹麦语、瑞典语、挪威语、芬兰语、法罗人语、冰岛语、爱尔兰语、苏格兰语和英语。 ·         ascii(US ASCII)校对规则: o        ascii_bin o        ascii_general_ci( 默认) ·         cp850(DOS西欧) 校对规则: o        cp850_bin o        cp850_general_ci( 默认) ·         dec8(DEC 西欧)校对规则: o        dec8_bin o        dec8_swedish_ci( 默认) ·         hp8(HP 西欧)校对规则: o        hp8_bin o        hp8_english_ci( 默认) ·         latin1(cp1252 西欧)校对规则: o        latin1_bin o        latin1_danish_ci o        latin1_general_ci o        latin1_general_cs o        latin1_german1_ci o        latin1_german2_ci o        latin1_spanish_ci o        latin1_swedish_ci( 默认) latin1是 默认字符集。latin1_swedish_ci是 默认的校对规则,它用于大多数MySQL客户。虽然经常说它以瑞典/芬兰 校对规则为基础,但瑞典和芬兰人不同意这种说法。 latin1_german1_ci和latin1_german2_ci校对规则基于DIN-1和DIN-2标准,这里DIN代表*Deutsches Institut für Normung*(德语等价于ANSI)。DIN-1被叫做“字典校对规则”,DIN-2被叫做“电话簿校对规则”。 o        latin1_german1_ci(字典)规则: ~~~ o                     Ä = a ~~~ ~~~ o                     Ö = O ~~~ ~~~ o                     Ü = U ~~~ ~~~ o                     ß = s ~~~ o        latin1_german2_ci(电话簿)规则: ~~~ o                     Ä = aE ~~~ ~~~ o                     Ö = OE ~~~ ~~~ o                     Ü = UE ~~~ ~~~ o                     ß = ss ~~~ 在 latin1_spanish_ci校对规则中,‘ñ’(n-tilde)是‘n’和‘o’之间的间隔字母。 ·         macroma(Mac西欧) 校对规则: o        macroman_bin o        macroman_general_ci( 默认) ·         swe7(7位瑞典语) 校对规则: o        swe7_bin o        swe7_swedish_ci( 默认) ### 10.10.3. 中欧字符集 我们还提供一些用于捷克共和国、斯洛伐克、匈牙利、罗马尼亚、斯罗纹尼亚、克罗地亚和波兰的字符集支持。 ·         cp1250(Windows中欧) 校对规则: o        cp1250_bin o        cp1250_croatian_ci o        cp1250_czech_cs o        cp1250_general_ci( 默认) ·         cp852(DOS 中欧)校对规则: o        cp852_bin o        cp852_general_ci( 默认) ·         keybcs2(DOS Kamenicky Czech-Slovak)校对规则: o        keybcs2_bin o        keybcs2_general_ci( 默认) ·         latin2(ISO 8859-2 中欧)校对规则: o        latin2_bin o        latin2_croatian_ci o        latin2_czech_cs o        latin2_general_ci( 默认) o        latin2_hungarian_ci ·         macce(Mac 中欧)校对规则: o        macce_bin o        macce_general_ci( 默认) ### 10.10.4. 南欧与中东字符集 MySQL支持的南欧和中东字符集包括亚美尼亚语、阿拉伯语、乔治亚语、希腊语、希伯莱语和土耳其语: ·         armscii8(ARMSCII-8 亚美尼亚语)校对规则: o        armscii8_bin o        armscii8_general_ci( 默认) ·         cp1256(阿拉伯语Windows) 校对规则: o        cp1256_bin o        cp1256_general_ci( 默认) ·         geostd8(GEOSTD8乔治亚语) 校对规则: o        geostd8_bin o        geostd8_general_ci( 默认) ·         greek(ISO 8859-7希腊语)校对规则: o        greek_bin o        greek_general_ci( 默认) ·         hebrew(ISO 8859-8希伯莱语)校对规则: o        hebrew_bin o        hebrew_general_ci( 默认) ·         latin5(ISO 8859-9 土耳其语)校对规则: o        latin5_bin o        latin5_turkish_ci( 默认) ### 10.10.5. 波罗的海字符集 波罗的海字符集覆盖爱沙尼亚语、拉脱维亚语和立陶宛语言。当前支持的两种波罗的海字符集: ·         cp1257(Windows波罗的海) 校对规则: o        cp1257_bin o        cp1257_general_ci( 默认) o        cp1257_lithuanian_ci ·         latin7(ISO 8859-13波罗的海)校对规则: o        latin7_bin o        latin7_estonian_cs o        latin7_general_ci( 默认) o        latin7_general_cs ### 10.10.6. 西里尔字符集 使用西里尔字符集和校对规则的有Belarusian、保加利亚、俄语和乌克兰语言。 ·         cp1251(Windows 西里尔)校对规则: o        cp1251_bin o        cp1251_bulgarian_ci o        cp1251_general_ci( 默认) o        cp1251_general_cs o        cp1251_ukrainian_ci ·         cp866(DOS 俄语)校对规则: o        cp866_bin o        cp866_general_ci( 默认) ·         koi8r(KOI8-R Relcom 俄语)校对规则: o        koi8r_bin o        koi8r_general_ci( 默认) ·         koi8u(KOI8-U 乌克兰语)校对规则: o        koi8u_bin o        koi8u_general_ci( 默认) ### 10.10.7. 亚洲字符集 [ 10.10.7.1. cp932字符集](#) 我们支持的亚洲字符集包括中文、日语、韩语和泰国语。这些可能比较复杂。例如,中文字符集必须考虑到上千种不同的字符。 ·         big5(Big5传统中文) 校对规则: o        big5_bin o        big5_chinese_ci( 默认) ·         cp932(SJIS Windows日语)校对规则: o        cp932_bin o        cp932_japanese_ci( 默认) ·         eucjpms(UJIS Windows日语)校对规则: o        eucjpms_bin o        eucjpms_japanese_ci( 默认) ·         euckr(EUC-KR 韩语)校对规则: o        euckr_bin o        euckr_korean_ci( 默认) ·         gb2312(GB2312 简体中文)校对规则: o        gb2312_bin o        gb2312_chinese_ci( 默认) ·         gbk(GBK简体中文) 校对规则: o        gbk_bin o        gbk_chinese_ci( 默认) ·         sjis(Shift-JIS 日语)校对规则: o        sjis_bin o        sjis_japanese_ci( 默认) ·         tis620(TIS620 泰国语)校对规则: o        tis620_bin o        tis620_thai_ci( 默认) ·         ujis(EUC-JP 日语)校对规则: o        ujis_bin o        ujis_japanese_ci( 默认) #### 10.10.7.1. cp932字符集 **为什么需要****cp932****?** 在MySQL中,sjis字符集对应于由IANA定义的Shift_JIS字符集,它支持JIS X0201和JIS X0208字符。(见 [ http://www.iana.org/assignments/character-sets](http://www.iana.org/assignments/character-sets)。) 但是,“SHIFT JIS”作为描述性术语的含义变得非常含糊不清,并且它常常包括由不同供应商定义的Shift_JIS扩展部分。 例如,使用在日本Windows环境中使用的“SHIFT JIS”是Microsoft对Shift_JIS的Microsoft扩展,它的准确名字是Microsoft Windows Codepage: 932或cp932。除由Shift_JIS支持的字符之外,cp932支持扩展字符,如NEC选择的IBM扩展字符和IBM扩展字符。 许多日本用户在使用这些扩展字符过程中碰到过一些问题。这些问题是由于以下情况引起的: ·         MySQL自动转换字符集。 ·         字符集通过Unicode转换(ucs2)。 ·         sjis字符集不支持这些扩展字符转换。 ·         从号称“SHIFT JIS”到Unicode的转换,存在一些转换规则,并且一些字符转换到Unicode依赖不同的转换规则。MySQL仅支持这些转换规则中的一种(在后面描述)。 MySQLcp932字符集可以解决这些转换问题。 因为MySQL支持字符集转换,将IANA Shift_JIS和 cp932分离为两种不同字符集是重要的,因为它们提供不同的转换规则。 **cp932****与****sjis****有什么不同?** cp932字符集与sjis存在以下不同点: ·         cp932支持NEC特殊字符、NEC选择的IBM扩展字符和IBM选择的字符。 ·         一些cp932字符有两个不同的编码点,这两种编码点转换为相同Unicode编码点。因此,当从Unicode转换回到cp932时,必须选择一个编码点。对于这种“相互转换”,使用由Microsoft推荐的转换规则。(见 [ http://support.microsoft.com/kb/170559/EN-US/](http://support.microsoft.com/kb/170559/EN-US/)。) 转换规则如下: o        如果字符在JIS X 0208 和NEC特殊字符中同时存在,使用JIS X 0208 的编码点。 o        如果字符在NEC特殊字符和IBM选择的字符中同时存在,使用NEC特殊字符的编码点。 o        如果字符在IBM选择的字符和NEC选择的IBM扩展字符中同时存在,使用IBM扩展字符的编码点。 关于cp932字符的Unicode 值的列表显示信息见[http://www.microsoft.com/globaldev/reference/dbcs/932.htm](http://www.microsoft.com/globaldev/reference/dbcs/932.htm)。对于cp932表中的带有下面有四位数字出现的字符的实体,数字代表相应的Unicode(ucs2)编码。对于表中有两个带下划线的数字出现的实体,择有一个以那两个数字开头的cp932字符值的范围。点击一个这种表的实体,将带你到一个页,该页显示每个以那些数字开头的cp932字符的Unicode值。 以下连接很重要。它们与下列字符集的编码相对应: o        NEC特殊字符: [ http://www.microsoft.com/globaldev/reference/dbcs/932/932_87.htm](http://www.microsoft.com/globaldev/reference/dbcs/932/932_87.htm) o        NEC选择的IBM扩展字符: ~~~ o                     http://www.microsoft.com/globaldev/reference/dbcs/932/932_ED.htm ~~~ ~~~ o                     http://www.microsoft.com/globaldev/reference/dbcs/932/932_EE.htm ~~~ o        IBM选择的字符: ~~~ o                     http://www.microsoft.com/globaldev/reference/dbcs/932/932_FA.htm ~~~ ~~~ o                     http://www.microsoft.com/globaldev/reference/dbcs/932/932_FB.htm ~~~ ~~~ o                     http://www.microsoft.com/globaldev/reference/dbcs/932/932_FC.htm ~~~ ·         cp932与eucjpms结合支持用户自定义字符的转换,并且解决sjis/ujis转换问题。详细信息,请参见[http://www.opengroup.or.jp/jvc/cde/sjis-euc-e.html](http://www.opengroup.or.jp/jvc/cde/sjis-euc-e.html)。 ·         对于一些字符,与ucs2之间的转换与sjis和cp932之间的转换是不同的。下表举例说明了这些不同。 转换到ucs2: <table border="1" cellpadding="0" id="table4"><tr><td> <p><span><b> <span>sjis</span></b></span><strong><span>/</span></strong><span><b><span>cp932</span></b></span><strong><span>值</span></strong></p></td> <td> <p><span><b> <span>sjis</span></b></span><strong><span>→ </span></strong><span><b> <span>ucs2</span></b></span><strong><span>转换</span></strong></p></td> <td> <p><span><b> <span>cp932</span></b></span><strong><span> </span><span>→ </span></strong> <span><b> <span>ucs2</span></b></span><strong><span>转换</span></strong></p></td> </tr><tr><td> <p><span>5C</span></p></td> <td> <p><span>005C</span></p></td> <td> <p><span>005C</span></p></td> </tr><tr><td> <p><span>7E</span></p></td> <td> <p><span>007E</span></p></td> <td> <p><span>007E</span></p></td> </tr><tr><td> <p><span>815C</span></p></td> <td> <p><span>2015</span></p></td> <td> <p><span>2015</span></p></td> </tr><tr><td> <p><span>815F</span></p></td> <td> <p><span>005C</span></p></td> <td> <p><span>FF3C</span></p></td> </tr><tr><td> <p><span>8160</span></p></td> <td> <p><span>301C</span></p></td> <td> <p><span>FF5E</span></p></td> </tr><tr><td> <p><span>8161</span></p></td> <td> <p><span>2016</span></p></td> <td> <p><span>2225</span></p></td> </tr><tr><td> <p><span>817C</span></p></td> <td> <p><span>2212</span></p></td> <td> <p><span>FF0D</span></p></td> </tr><tr><td> <p><span>8191</span></p></td> <td> <p><span>00a2</span></p></td> <td> <p><span>FFE0</span></p></td> </tr><tr><td> <p><span>8192</span></p></td> <td> <p><span>00a3</span></p></td> <td> <p><span>FFE1</span></p></td> </tr><tr><td> <p><span>81Ca</span></p></td> <td> <p><span>00aC</span></p></td> <td> <p><span>FFE2</span></p></td> </tr></table> 从ucs2转换: <table border="1" cellpadding="0" id="table5"><tr><td> <p><span><b> <span>ucs2</span></b></span><strong><span>值</span></strong></p></td> <td> <p><span><b> <span>ucs2</span></b></span><strong><span> </span><span>→</span><span> </span></strong><span><b> <span>sjis</span></b></span><strong><span>转换</span></strong></p></td> <td> <p><span><b> <span>ucs2</span></b></span><strong><span> </span><span>→</span><span> </span></strong><span><b> <span>cp932</span></b></span><strong><span>转换</span></strong></p></td> </tr><tr><td> <p><span>005C</span></p></td> <td> <p><span>815F</span></p></td> <td> <p><span>5C</span></p></td> </tr><tr><td> <p><span>007E</span></p></td> <td> <p><span>7E</span></p></td> <td> <p><span>7E</span></p></td> </tr><tr><td> <p><span>00a2</span></p></td> <td> <p><span>8191</span></p></td> <td> <p><span>3F</span></p></td> </tr><tr><td> <p><span>00a3</span></p></td> <td> <p><span>8192</span></p></td> <td> <p><span>3F</span></p></td> </tr><tr><td> <p><span>00aC</span></p></td> <td> <p><span>81Ca</span></p></td> <td> <p><span>3F</span></p></td> </tr><tr><td> <p><span>2015</span></p></td> <td> <p><span>815C</span></p></td> <td> <p><span>815C</span></p></td> </tr><tr><td> <p><span>2016</span></p></td> <td> <p><span>8161</span></p></td> <td> <p><span>3F</span></p></td> </tr><tr><td> <p><span>2212</span></p></td> <td> <p><span>817C</span></p></td> <td> <p><span>3F</span></p></td> </tr><tr><td> <p><span>2225</span></p></td> <td> <p><span>3F</span></p></td> <td> <p><span>8161</span></p></td> </tr><tr><td> <p><span>301C</span></p></td> <td> <p><span>8160</span></p></td> <td> <p><span>3F</span></p></td> </tr><tr><td> <p><span>FF0D</span></p></td> <td> <p><span>3F</span></p></td> <td> <p><span>817C</span></p></td> </tr><tr><td> <p><span>FF3C</span></p></td> <td> <p><span>3F</span></p></td> <td> <p><span>815F</span></p></td> </tr><tr><td> <p><span>FF5E</span></p></td> <td> <p><span>3F</span></p></td> <td> <p><span>8160</span></p></td> </tr><tr><td> <p><span>FFE0</span></p></td> <td> <p><span>3F</span></p></td> <td> <p><span>8191</span></p></td> </tr><tr><td> <p><span>FFE1</span></p></td> <td> <p><span>3F</span></p></td> <td> <p><span>8192</span></p></td> </tr><tr><td> <p><span>FFE2</span></p></td> <td> <p><span>3F</span></p></td> <td> <p><span>81Ca</span></p></td> </tr></table> 这是MySQL参考手册的翻译版本,关于MySQL参考手册,请访问[dev.mysql.com](http://dev.mysql.com/doc/mysql/en)。 原始参考手册为英文版,与英文版参考手册相比,本翻译版可能不是最新的。