| |||||||||||||||||||||||||||||||||||||||||||||||
文章所属标签: 科技IT | |||||||||||||||||||||||||||||||||||||||||||||||
字符集支持
输出实际上包含另一列,这里为了让例子在页面上显示更合适,没显示出来 任一给出的字符集至少包含一个collation. 它可能包含多个 collations. 要列出一个字符集的 collations , 使用 SHOW COLLATION 语句. 例如, 要看latin1 (``ISO-8859-1 West European'')的collations, 使用这个语句来找到哪些名字以latin1 开头的collation
latin1 collations 有下列含义: Collation 含义
Collations 有这些一般特性: ·两个不同字符集没法拥有同一个collation. ·每个字符集有一个默认 collation. 例如, latin1 的默认 collation 是 latin1_swedish_ci. ·collation 的命名有个约定: 他们由所关联的字符集的名字打头,他们通常包含一个 语言名, 并以 _ci (case insensitive大小写不敏感), 或者 _cs (case sensitive大小写敏感), 或者 _bin (binary二进制). 10.3 决定默认字符集和 Collation 有四个级别上的默认字符集和collation设置: 服务器,数据库,表和连接。下面的描述 可能看起来复杂,不过实践中得出多级默认设置可以带来自然而然的结果。 10.3.1 服务器级字符集和 Collation MySQL服务器有一个服务器级别的字符集和 collation, 不能为空。 MySQL 这样决定服务器级的字符集和collation ·当服务器开始按照有效选项设置 ·运行期间按照变量 在服务器级别,决定是很简单的,依靠你执行mysqld时使用的选项来决定服务器字符集 和collation。你可以使用--default-character-set 来指定字符集,并且和这个一起 还可以为collation加上--default-collation 。如果你不指定字符集,就相当于说 --default-character-set=latin1。如果你只指定了字符集(例如,latin1)但是没有指定 collation,就相当于 --default-charset=latin1 --default-collation=latin1_swedish_ci 因为 latin1_swedish_ci是latin1字符集的默认collation, 因此下面三个命令都具有 同样效果:
有个改变这个设置的方法是重新编译,如果你想编译源码来改变默认的服务器字符集和 collation,在configure使加上参数--with-charset 和 --with-collation ,例如:
或者:
mysqld 和configure 都会核实字符集/collation的结合是否有效,如果无效,这两个 程序都会报错并中止。 现行服务器字符集和collation 是和character_set_server 和 collation_server 这两个系统变量的值一样,这些变量可以在运行时更改 10.3.2 数据库字符集和 Collation 每个数据库都有一个数据库字符集和数据库collation,并且不能为空,create DATABASE 和 alter DATABASE 语句有专门指明数据库字符集和collation的可选子句:
例子:
MySQL可以这样选择数据库字符集和数据库collation: ·如果 CHARACTER SET X 和 COLLATE Y 被指定了, 那么字符集是 X collation 是 Y. ·如果 CHARACTER SET X 被指定,但是没有指定 COLLATE, 那么字符集是 X collation 是默认collation. ·否则, 就用服务器字符集和服务器 collation. MySQL 的 create DATABASE ... DEFAULT CHARACTER SET ... 语法类似于标准 SQL 的 create SCHEMA ... CHARACTER SET ... 语法. 因为这样, 就可能在同一个MySQL 服务器上创建具有不同字符集和collation的数据库。 如果在建表的语句里没有指定表的字符集和collation,那么数据库字符集和 collation 就作为表的字符集和collation的默认值. 它们没有别的作用。 默认数据库的字符集和 collation是和 character_set_database 以及 collation_database 这两个系统变量的值一样。 当默认数据库更改时服务程序会设置 这些变量的值。如果没有默认数据库, 变量的值会和配套的服务器级系统变量 character_set_server 以及 collation_server的值一致. 10.3.3 表字符集和 Collation 每个表有一个表字符集以及一个表collation,不能为空。create TABLE 和 alter TABLE 语句有可选子句指定表字符集和collation。
例子:
MySQL 通过下面的方法选择表字符集和collation: ·如果 CHARACTER SET X 和 COLLATE Y 都被指定了, 那么字符集就是 X collation 是Y ·如果只指定了CHARACTER SET X 而没有指定 COLLATE, 那么字符集为 X 并配默认的 collation. ·否则就使用数据库字符集和 collation. 表字符集和 collation 用来在没有指定个别列字符集和列collation的时候做为它们 的默认值。表字符集和 collation 是MySQL 的扩展;在标准SQL里没有这种东西 10.3.4 列字符集和 Collation 每个``character'' 列(是指列属性为CHAR, VARCHAR, 或 TEXT的)都有一个列字符集 和一个列collation,不能为空。列定义语句有可选子句指定列字符集和collation:
MySQL 这样选择列字符集和collation: ·如果 CHARACTER SET X 和 COLLATE Y 都被指定了, 那么字符集就是 X collation 就是 Y. ·如果指定了 CHARACTER SET X 但没有指定 COLLATE, 那么字符集是 X 并配默认的collation. ·否则,就用表字符集和 collation. CHARACTER SET 和 COLLATE 子句是标准SQL. 10.3.5 字符集和 Collation 分配的例子 下面的例子显示了 MySQL 怎样决定默认的字符集和collation的值: 例子1:表+列定义
这里我们有一个用latin1的字符集和latin1_german1_ci collation的列。 定义非常明显,所以很简单。注意把一个latin1 的列存到一个latin2的表里不会有问题 例子2:表+列定义
这次我们有一列是latin1字符集加默认的collation。现在,虽然它看上去很自然, 但是默认的collation却不是从表级继承而来。事实上,因为latin1的默认collation 始终是latin1_swedish_ci,所以c1列的collation是latin1_swedish_ci (而不是 latin1_danish_ci). 例子3:表+列定义
我们有一个默认字符集和默认collation的列。在这个环境下,MySQL向上到表级决定 列字符集和collation。所以,c1的列字符集是latin1,它的collation是 latin1_danish_ci 例子4:数据库+表+列定义
我们创建了一个没有指定列字符集和collation的列。我们也没有指定表级字符集和 collation。在这个条件下,MySQL向上到数据库级决定。(数据库的设置变为表的设置, 之后成为列的设置),所以c1的列字符集是latin2,collation是latin2_czech_ci 10.3.6 连接的字符集和Collations 一些字符集和collation和用户对服务器的作用结合。有些在前面已经提及了: ·服务器的字符集和collation和 character_set_server 及 collation_server 变量 的值一样 ·默认数据库的字符集和collation和 character_set_database 及 collation_database 变量的值一样. 附加的字符集和collation 变量被引入用来处理服务器和客户端之间连接得通信。每个 客户端都有连接相关的字符集和collation变量。 想想"连接"是什么:是你连到服务器时作的事情。客户端通过这条连接发送SQL语句, 比如查询,服务器则通过这条连接给客户端送回回应,比如查询结果结果集合,这导致 了客户端处理字符集和collation的一些问题,它们每个都可以按照系统变量来回答: ·当查询离开客户端的时候应该是什么字符集的?服务器用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' 语句相当于下面三个语句:
把character_set_connection 设置成x也会把collation_connection 设置成默认 collation x SET CHARACTER SET 是类似的,不过是把连接字符集和collation设置成那些默认数据库。 SET CHARACTER SET x 语句相当于这三个语句:
当一个客户连接,它向服务程序发送它想使用的字符集的名字,服务程序把 character_set_client, character_set_results, 和 character_set_connection 这些变量设置成那个字符集(事实上,服务程序使用字符集执行了SET NAMES 操作) 如果你不想用默认字符集,使用 Mysql 客户端程序不需要每次启动时执行SET NAMES 。 你可以在mysql 执行语句行加上--default-character-set 这个选项,或者在你的选项 文件里加上。比如,下面的选项文件设置使你每次执行mysql程序时把默认字符集变量 改成 koi8r:
例如:假设column1定义是 CHAR(5) CHARACTER SET latin2。如果你不用SET NAMES 或者 SET CHARACTER SET,那么对于你的 select column1 FROM t 请求,服务程序 会把column1 的所有值用连接建立时客户端指定的字符集来回送。另一方面,如果你 用了 SET NAMES 'latin1' or SET CHARACTER SET latin1 ,那么在送回结果之前, 服务程序会把 latin2 的值转成latin1,如果里面有两种字符集里都没有的字符, 转化会有损耗。 如果你不希望服务程序作任何转换,就把character_set_results 设置成 NULL
10.3.7. 字符串文字字符集和collation 每个字符串文字都有自己的字符集和collation,不能为空 一个字符串文字可能有一个可选字符集introducer和COLLATION子句:
例如:
对于简单语句 select 'string',字符串的字符集和collation是由两个系统变量 character_set_connection 和 collation_connection 定义的。 _charset_name 表达式正式情况下被叫做 introducer .它告诉分析器"下面的字符串 是使用 X 字符集的。"因为这在以前造成很多人的困扰,我们强调一下introducer 并不作任何转换,严格来讲并不改变字符串的值,只是一个符号。introducer 在 标准16进制文字前和数字16进制记法前都是合法的(x'literal' 和 0xnnnn), 在?前面也是合法的(当在程序设计语言接口里使用预备语句时作参数替换) 例如:
MySQL 这样决定一个文字的字符集和collation: ·如果 _X 和 COLLATE Y 都被指定了,那么字符集就是 X collation 是 Y ·如果 指定了 _X 而没有指定 COLLATE ,那么字符集是 X collation 是 X 的默认 collation ·否则,由系统变量 character_set_connection 和 collation_connection 决定字符集 和collation 例如: ·一个字符集是 latin1 而collation是 latin1_german1_ci 的字符串:
·一个字符集是 latin1 以及其配套默认collation的(latin1_swedish_ci)字符串:
·一个连接默认字符集和collation的字符串:
字符集 introducer 和 COLLATE 子句是符合标准 SQL 规则的工具 10.3.8. 在 SQL 语句里使用 COLLATE 通过 COLLATE 子句,你可以在比较时覆盖替换掉任何默认collation, COLLATE 可以用 在SQL 语句的很多部分里,这里是一些例子: ·在 ORDER BY 里:
·在 AS 里:
·在GROUP BY里 :
·在集合函数里:
·在DISTINCT里
·在where 里:
·在HAVING里:
User Comments Posted by [name withheld] on January 14 2005 2:33pm 在不同的列/表里:
在collation 之间比较列的时候能够避免出错信息。 10.3.9. COLLATE 子句优先级 COLLATE子句具有高优先级(比||高),所以下面两个表达式是相同的:
10.3.10. BINARY 运算 BINARY 运算是COLLATE 子句的速记法,BINARY 'x' 和 'x' COLLATE y 是相同的, y 是字符集 'x' 的二元collation 的名字。每个字符集都有二元 collation。例如, latin1 字符集的 collation 是latin1_bin,所以如果列 a 是latin1 字符集,下面 两个语句有同样效果:
10.3.11. 一些决定collation 比较棘手的情况 在绝大多数查询里,MySQL 用什么collation来进行比较操作都是很显而易见的,例如, 在下面的情况里,很显然collation 应该是"列 x 的列 collation":
但是,当卷入了多操作数时,就很难搞了,例如:
这个查询应该使用列 x 的collation 呢,还是使用字符串'Y' 的? 标准SQL 使用被叫做``coercibility'' 的规则来解决这个问题。本质就是:因为 x 和 'Y' 都有collation ,优先使用谁的collation呢?这很复杂,不过下面的规则能 应付大多数情况: ·一个COLLATE 子句的 coercibility 是0 (也就是根本不coercible) ·两个具有不同collation 的字符串连结的 coercibility 是1 ·一个列的 collation 的 coercibility 是 2 ·一个文字型的collation 的 coercibility 是3。 那些规则这样解决含混: ·使用具有最低 coercibility 值的collation ·如果两边具有相同的 coercibility, 如果两个collation 不同那就是错误。 例如:
COERCIBILITY() 函数可以用来判断一个字符串表达式的coercibility:
User Comments Posted by Thierry Danard on November 5 2004 10:34pm 对于数据库引擎来说显而易见的排序并不是总那么显而易见(version 4.1). 一个没有带类似于"select concat(mycolumn, '%') from mytable "这样的排序指令 的查询在"mycolumn" 和"%"的字符集不相同的情况下不会工作。 在我这里,整个数据库使用 UTF-8, 默认情况下, '%' 假设是 latin1, causing an error to be triggered。 10.3.12. Collations Must Be for the Right Character Set 记得说过每个字符集都有一个或者多个collation,每个collation只和一个字符集关联。 因此,下面的语句会导致错误,因为 latin2_bin 这个collation 和 latin1 这个字符集 不配套。
在某些情况下,在 MySQL 4.1 前工作的表达式会在MySQL 4.1以后的版本失败, 如果你在帐号里没有字符集和collation的话。例如,在 MySQL 4.1 前,这个语句 会这样工作:
升级到MySQL 4.1 以后,语句失效:
发生这个的原因是username 使用utf8存储(参看10.6节),因此, USER() 函数 和文字型字符串'@'具有不同的字符集(当然也是不同collation):
解决的一个方法是告诉MySQL把文字型字符串翻译成utf8:
另一个方法是把连接的字符集和collation改成utf8,你可以使用SET NAMES 'utf8' 或者直接设置两个系统变量character_set_connection 和 collation_connection 的值来达到这个目的。 10.3.13. Collation 的效果的一个例子 假设表 T 里的列 X 具有这些 latin1 的列值:
并且假设这些列值可以用下列语句找回:
在这张表中列出了不同collation 的结果值的结果排序
这张表显示了如果我们在一个 ORDER BY 子句里使用不同collation 会有什么样的效果 的例子,导致这种不同排序结果的字符是上面有两个点的 U,在德语里叫做U-曲音, 不过我们叫做U-分音符 ·第一列显示了使用瑞典/芬兰 collation 规则的 select 的结果,U-分音符 通过Y归类 ·第二列显示了使用德语DIN-1 规则的select 语句的结果,U-分音符通过U归类 ·第三列显示了使用德语DIN-2 规则的select 语句的结果,U-分音符通过UE归类 三种不同的collation ,三种不同的结果,这是MySQL 在这里的处理。通过使用合适的 collation,你可以选择你想要的排序次序。 |
MySQL 字符集支持(转自Jeikul的blog)
最新推荐文章于 2024-08-15 16:45:01 发布