use case
首先看个例子:
有个user 表
user( username varchar(5) character set utf8collate utf8_general_ci);
有记录('username');和('username');
使用 select * from user where username='username'; 将会选出两条数据
然后将username的collate改为utf8_bin;
user( username varchar(5) character set utf8 collate utf8_bin);
再使用 select * from user where username='username'; 将会选出第一条数据
这是为什么呢?请往下看:
字符集(character set)是一套符号和编码。校对规则(collate)是在字符集内用于比较字符的一套规则。让我们使用一个假想字符集的例子来区别清楚。
假设我们有一个字母表使用了四个字母:‘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)然后比较编码。我们称这是一个大小写不敏感的 校对规则。比二元校对规则复杂一些。
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。
