MySQL字符集,Collation

先转一别人的学习文章做个引子和基础
http://logzgh.itpub.net/post/3185/467401

在以前用oracle的时候,很少关于它的collation方法,但是在mysql中,这点不加注意的话,却有可能会出现问题。

问题是这样的:
一张test的表,字符集采用的latin1。

select to_id from test where to_id='cn象_王';
+---------------+
| to_id |
+---------------+
| cn陶_陶 |
| cn象_王 |
+---------------+
2 rows in set (0.00 sec)


取cn象_王的数据,居然把cn陶_陶的数据也取回来了。


这显然是不允许的。


查看它们的编码:

(root@im_offlog1a)[test]> select hex('cn陶_陶');
+----------------+
| hex('cn陶_陶') |
+----------------+
| 636ECCD55FCCD5 |
+----------------+
1 row in set (0.00 sec)

(root@im_offlog1a)[test]> select hex('cn象_王');
+----------------+
| hex('cn象_王') |
+----------------+
| 636ECFF35FCDF5 |
+----------------+
1 row in set (0.00 sec)

编码的确是不一样的,但是为什么mysql会认为这两条记录是一样的呢?

一开始我们就把问题定位于collation引起的问题。

show variables查看
| collation_connection | latin1_swedish_ci
| collation_database | latin1_swedish_ci
| collation_server | latin1_swedish_ci


手工把这些参数修改为latin1_bin,结果居然一样。这下感觉真是奇怪了。

这里先解释一下mysql collation的命名规则:
它们以其相关的字符集名开始,通常包括一个语言名,并且以_ci(大小写不敏感)、_cs(大小写敏感)或_bin(二元)结束

比如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 现代西班牙


最后我们将表格重建,手工指定表格级别的collation为latin1_bin。
这个问题就得到了解决。


那么问题又来了,为什么我前面手工测试latin1_bin时不生效呢?

原来MySQL按照下面的方式选择表字符集和 校对规则:
如果指定了CHARACTER SET X和COLLATE Y,那么采用CHARACTER SET X和COLLATE Y。
如果指定了CHARACTER SET X而没有指定COLLATE Y,那么采用CHARACTER SET X和CHARACTER SET X的默认校对规则。
否则,采用服务器字符集和服务器校对规则。

而我们在建表的时候指定了character set,所以它永远是采用对应的默认的校对规则。

当然我们其实也没必要重建表格,只需要alter table db_allot CONVERT TO CHARACTER SET latin1 COLLATE latin1_bin这样转换即可。

另外建议collation都尽量采用字符集相应的bin类型的校对规则,这样不容易出错。


文章出处:http://www.diybl.com/course/7_databases/sql/sqlServer/200896/139253.html

 

mysql服务器中有六个关键位置使用了字符集的概念,他们是:client 、connection、database、results、server 、system。
       1、其中client是客户端使用的字符集,相当于网页中的字符集设置如下
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">。
       2、其中的connection是连接数据库的字符集设置类型,如果php没有指明连接数据库使用的字符集类型
就按照服务器端默认的字符集设置。
       3、其中database是数据库服务器中某个库使用的字符集设定,如果建库时没有指明,将使用服务器安装
时指定的字符集设置。
       4、results是数据库给客户端返回时使用的字符集设定,如果没有指明,使用服务器默认的字符集。
       5、server是服务器安装时指定的默认字符集设定。
       6、system是数据库系统使用的字符集设定。

      system一般默认是utf-8字符集,server是最高的字符集设定,database没有单独设定就按照server的字符
集设定,其他都是按照server的设定设置字符集。还有,数据库内的每个表和字段也都有字符集的概念,一般都
是根据上一级结构决定自身的字符集,比如表就根据database库的设定决定自己的字符集,字段根据表来决定自己
的字符集。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值