在之前可能都不知道由于昨天的面试 所感慨 平时要好好研究每一个知识点 不仅仅知道怎么用还要知道他是什么 他有什么意义他有什么作用 他和别的区别 他。。。等等问题。
一下主要参考MySQL手册 最近要好好读。主要讨论以下主题:
·         什么是字符集和校对规则?
·         多级默认系统
·         字符集语法
·         MySQL字符集校对。
·         Unicode字符集
·         utf8_unicode_ci 和utf8_general_ci 的含义和区别
MySQL5.1中的字符集支持包括在MyISAM、MEMORY和InnoDB存储引擎中。
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(二元)校对规则。 _bin
但是,如果我们希望小写字母和大写字母是等价的,应该怎样?那么,我们将至少有两个规则:(1)把小写字母‘a’和‘b’视为与‘A’和‘B’等价;(2)然后比较编码。我们称这是一个大小写不敏感的 校对规则。比二元校对规则复杂一些。 _ci _cs



MySQL5.1能够做这些事情:
·         使用多种字符集来存储字符串
·         使用多种校对规则来比较字符串
·         在同一台服务器、同一个数据库或甚至在同一个表中使用不同字符集或校对规则来混合字符串
·         允许定义任何级别的字符集和校对规则
2.MySQL中的字符集和校对
MySQL服务器能够支持多种字符集。可以使用SHOW CHARACTER SET语句列出可用的字符集:
mysql> SHOW CHARACTER SET;  任何一个给定的字符集至少有一个校对规则。它可能有几个校对规则。 要想列出一个字符集的校对规则,使用SHOW COLLATION语句。例如,要想查看utf8字符集的 校对规则,使用下面的语句查找那些名字以utf8开头的 校对规则:
mysql> SHOW COLLATION LIKE 'utf8%';  校对规则一般有这些特征: ·         两个不同的字符集不能有相同的校对规则。
·         每个字符集有一个默认校对规则。例如,latin1默认校对规则是latin1_swedish_ci。
·         存在校对规则命名约定:它们以其相关的字符集名开始,通常包括一个语言名,并且以_ci(大小写不敏感)、_cs(大小写敏感)或_bin(二元)结束。
3. 确定默认字符集和校对字符集和校对规则有4个级别的默认设置:服务器级、数据库级、表级和连接级。以下描述可能显得复杂,但是在实际应用中可以发现使用多种级别会使结果自然而明显。3.1. 服务器字符集和校对MySQL服务器有一个服务器字符集和一个服务器校对规则,它们均不能设置为空。MySQL按照如下方法确定服务器字符集和服务器校对规则:
·         当服务器启动时根据有效的选项设置
·         根据运行时的设定值
在服务器级别,确定方法很简单。当启动mysqld时,根据使用的初始选项设置来确定服务器字符集和 校对规则。可以使用--default-character-set设置字符集,并且可以在字符集后面为 校对规则添加--default-collation。如果没有指定一个字符集,那就与--default-character-set=latin1相同。如果你仅指定了一个字符集(例如,latin1),但是没有指定一个 校对规则,那就与--default-charset=latin1 --default-collatinotallow=latin1_swedish_ci相同,因为latin1_swedish_ci是latin1的默认校对规则。因此,以下三个命令有相同的效果:
shell> mysqld
shell> mysqld --default-character-set=latin1
shell> mysqld --default-character-set=latin1 /
          --default-collatinotallow=latin1_swedish_ci
更改设定值的一个方法是通过重新编译。如果希望在从源程序构建时更改默认服务器字符集和校对规则,使用:--with-charset和--with-collation作为configure的参量。例如:
shell> ./configure --with-charset=latin1 或者:
shell> ./configure --with-charset=latin1 /
          --with-collatinotallow=latin1_german1_ci
mysqldconfigure都验证字符集/校对规则组合是否有效。如果无效,每个程序都显示一个错误信息,然后终止。
当前的服务器字符集和校对规则可以用作character_set_server和collation_server系统变量的值。在运行时能够改变这些变量的值。
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)具有相同的值。
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中没有。
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。
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。
3.6. 连接字符集和校对一些字符集和校对规则系统变量与客户端和服务器的交互有关。在前面的章节中已经提到过部分内容:·         服务器字符集和校对规则可以用作character_set_server和collation_server变量的值。
·         默认数据库的字符集和校对规则可以用作character_set_database和collation_database变量的值。
在客户端和服务器的连接处理中也涉及了字符集和校对规则变量。每一个客户端有一个连接相关的字符集和校对规则变量。

PHP通过character_set_client告诉MYSQL,php存入数据库的是什么编码方式
PHP通过character_set_results告诉MYSQL,php需要取什么样编码的数据
PHP通过character_set_connection告诉MYSQL,PHP查询中的文本,使用什么编码
还有字符串文字字符集和校对 将以后列举 现不在列出 COLLATE

4. Unicode字符集MySQL有两种Unicode字符集。你能够使用这些字符集保存大约650种语言的文本。
·         ucs2 (UCS-2 Unicode) (UTF-8 Unicode)

UTF8字符集(转换Unicode表示)是存储Unicode数据的一种可选方法。它根据 RFC 3629执行。UTF8字符集的思想是不同Unicode字符采用变长字节序列编码:
·         基本拉丁字母、数字和标点符号使用一个字节。
·         大多数的欧洲和中东手写字母适合两个字节序列:扩展的拉丁字母(包括发音符号、长音符号、重音符号、低音符号和其它音符)、西里尔字母、希腊语、亚美尼亚语、希伯来语、阿拉伯语、叙利亚语和其它语言。
·         韩语、中文和日本象形文字使用三个字节序列。

5. utf8_unicode_ci 和 utf8_general_ci 区别utf8_unicode_ci校对规则是根据Unicode校对规则算法(UCA)执行的,
当前,utf8_unicode_ci校对规则仅部分支持Unicode校对规则算法。一些字符还是不能支持。并且,不能完全支持组合的记号。这主要影响越南和俄罗斯的一些少数民族语言,如:Udmurt 、Tatar、Bashkir和Mari。
utf8_unicode_ci的最主要的特色是支持扩展,即当把一个字母看作与其它字母组合相等时。例如,在德语和一些其它语言中‘s’等于‘ss’。
utf8_general_ci是一个遗留的 校对规则,不支持扩展。它仅能够在字符之间进行逐个比较。这意味着utf8_general_ci校对规则进行的比较速度很快,但是与使用utf8_unicode_ci的 校对规则相比,比较正确性较差)。
例如,使用utf8_general_ci和utf8_unicode_ci两种 校对规则下面的比较相等:
A = A  O = O  U = U 两种校对规则之间的区别是,对于utf8_general_ci下面的等式成立:
s = s 但是,对于utf8_unicode_ci下面等式成立:
s = ss 对于一种语言仅当使用utf8_unicode_ci排序做的不好时,才执行与具体语言相关的utf8字符集 校对规则。例如,对于德语和法语,utf8_unicode_ci工作的很好,因此不再需要为这两种语言创建特殊的utf8校对规则。
utf8_general_ci也适用与德语和法语,除了‘s’等于‘s’,而不是‘ss’之外。如果你的应用能够接受这些,那么应该使用utf8_general_ci,因为它速度快。否则,使用utf8_unicode_ci,因为它比较准确。
utf8_swedish_ci,与其它语言相关的utf8的校对规则相似,来源于utf8_unicode_ci,使用额外的语言规则。例如,在瑞典语中,以下的关系式成立,它在德语和法语中不成立:
U = Y < O