վÄÚËÑË÷: ÇëÊäÈëËÑË÷¹ؼü´Ê
µ±ǰҳÃæ: ÔÚÏßÎĵµÊ×ҳ > MySQL 5.1²ο¼ÊֲáÖÐÎİæ

Chapter 10. Character Set Support - MySQL 5.1²ο¼ÊֲáÖÐÎİæ

ç¬�10章:字符集支æŒ�

本章讨论以下主题ï¼�

·         什么是字符集和校对规则ï¼�

·         多级默认系统

·         字符集语æ³�

·         相关函数和运ç®�

·         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支持的字符集和校对â€�。)

任何一个给定的字符集至少有一个校对规则。它可能有几个校对规则ã€�

要想列出一个字符集的校对规则,使用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校对规则有下面的含义ï¼�

校对规则

含义

latin1_german1_ci

德国DIN-1

latin1_swedish_ci

瑞典/芬兰

latin1_danish_ci

丹麦/挪威

latin1_german2_ci

德国 DIN-2

latin1_bin

符合latin1编码的二进制

latin1_general_ci

多种语言(西欧)

latin1_general_cs

多种语言(西欧ISO),大小写敏æ„�

latin1_spanish_ci

现代西班ç‰�

校对规则一般有这些特征ï¼�

·         两个不同的字符集不能有相同的校对规则ã€�

·         每个字符集有一ä¸�默认校对规则。例如,latin1默认校对规则æ˜�latin1_swedish_ciã€�

·         存在校对规则命名约定:它们以其相关的字符集名开始,通常包括一个语言名,并且ä»�_ci(大小写不敏感)ã€�_cs(大小写敏感)或_bin(二元)结束ã€�

10.3. 确定默认字符集和校对

字符集和校对规则æœ�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'å’� 0xnnnn)中是合法的,以å��ï¼�(当在一个编程语言接口中使用预处理的语句时进行参数替换)ã€�

例如ï¼�

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当前所用的ã€�

这样上述规则可以模糊解决ï¼�

·         使用最低的可压缩性值的校对规则ã€�

·         如果两侧有相同的可压缩性,那么如果校对规则不同则发生错误ã€�

例如ï¼�

column1 = 'A'

使用column1的校对规åˆ�

column1 = 'A' COLLATE x

使用'A'的校对规åˆ�

column1 COLLATE x = 'A' COLLATE y

错误

使用COERCIBILITY()函数确定一个字符串表达式的可压缩性:

mysql> SELECT COERCIBILITY('A' COLLATE latin1_swedish_ci);
        -> 0
mysql> SELECT COERCIBILITY(VERSION());
        -> 3
mysql> SELECT COERCIBILITY('A');
        -> 4

è§�12.9.3节,“信息函数â€�ã€�

没有系统常数或可忽略的压缩性。函数如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;

使用不同校对规则的列值结果排序见下表ï¼�

latin1_swedish_ci

latin1_german1_ci

latin1_german2_ci

Muffler

Muffler

Müller

MX系统

Müller

Muffler

Müller

MX系统

MX系统

MySQL

MySQL

MySQL

本表显示了我们在ORDER BY字句中使用不同所校对规则的效果的示例。在本例中导致不同排序的字符是上面带有两个圆点的Uï¼�ü),它在德语中发音为"U-umlaut"ã€�

·         第一列显示的是使用瑞å…�/芬兰校对规则çš�SELECT语句的结果,它被称作U-umlaut使用Y排序ã€�

·         第二列显示的是使用德è¯�DIN-1校对规则çš�SELECT语句的结果,它被称作U-umlaut使用U排序ã€�

·         第三列显示的是使用德è¯�DIN-2校对规则çš�SELECT语句的结果,它被称作U-umlaut使用UE排序ã€�

10.4. 字符集支持影响到的操ä½�

本节讨论åœ�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语法â€�ã€�

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语法â€�ã€�

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语法â€�

SHOW CREATE TABLEä¸�SHOW CREATE DATABASE相似,但是显示创建给定数据库çš�CREATE TABLE语句。列定义显示任何字符集规格,并且表选项包括字符集信息ã€�

è§�13.5.4.5节,“SHOW CREATE TABLE语法â€�

当以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语法â€�ã€�

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 主页ã€�

当前ï¼�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节,“连接字符集和校对â€�),或者在客户端执行转捀€‚在客户端执行转换效率较高,但这种选项并不能使用于全部客户端ã€�

如果你正在一个语句中使用(例如)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支持的字符集和校å¯�

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/。此校对规则使用UCA 4.0.0版本砝码键:http://www.unicode.org/Public/UC一ä¸�/4.0.0/一ä¸�llkeys-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. 亚洲字符é›�

我们支持的亚洲字符集包括中文、日语、韩语和泰国语。这些可能比较复杂。例如,中文字符集必须考虑到上千种不同的字符ã€�

·         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。)

但是,â€�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/。)

转换规则如下ï¼�

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。对äº�cp932表中的带有下面有四位数字出现的字符的实体,数字代表相应的Unicodeï¼�ucs2)编码。对于表中有两个带下划线的数字出现的实体,择有一个以那两个数字开头的cp932字符值的范围。点击一个这种表的实体,将带你到一个页,该页显示每个以那些数字开头的cp932字符çš�Unicode值ã€�

以下连接很重要。它们与下列字符集的编码相对应:

o        NEC特殊字符ï¼�

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ã€�

·         对于一些字符,ä¸�ucs2之间的转换与sjiså’�cp932之间的转换是不同的。下表举例说明了这些不同ã€�

转换åˆ�ucs2ï¼�

sjis/cp932�

sjisâ†� ucs2转换

cp932 â†� ucs2转换

5C

005C

005C

7E

007E

007E

815C

2015

2015

815F

005C

FF3C

8160

301C

FF5E

8161

2016

2225

817C

2212

FF0D

8191

00a2

FFE0

8192

00a3

FFE1

81Ca

00aC

FFE2

ä»�ucs2转换ï¼�

ucs2�

ucs2 â†� sjis转换

ucs2 â†� cp932转换

005C

815F

5C

007E

7E

7E

00a2

8191

3F

00a3

8192

3F

00aC

81Ca

3F

2015

815C

815C

2016

8161

3F

2212

817C

3F

2225

3F

8161

301C

8160

3F

FF0D

3F

817C

FF3C

3F

815F

FF5E

3F

8160

FFE0

3F

8191

FFE1

3F

8192

FFE2

3F

81Ca


这是MySQL参考手册的翻译版本,关于MySQL参考手册,请访é—�dev.mysql.comã€� 原始参考手册为英文版,与英文版参考手册相比,本翻译版可能不是最新的ã€�