表1和表2是不同数据库中的同名table,但是发现表1中的查询和表2中的查询有区别,(事实是表1的查询是对的。) 表1的查询结果 mysql> select * from slot_value where slot_type_id='09FDBC8081294EF09D65F909E7FD9DE3' and slot_value='a bout de souffle' ; +---------+----------------------------------+-------------------+ | id | slot_type_id | slot_value | +---------+----------------------------------+-------------------+ | 2316211 | 09FDBC8081294EF09D65F909E7FD9DE3 | a bout de souffle | +---------+----------------------------------+-------------------+ 1 row in set (0.02 sec) mysql> select * from slot_value where slot_type_id='09FDBC8081294EF09D65F909E7FD9DE3' and slot_value='à bout de souffle' ;; +---------+----------------------------------+--------------------+ | id | slot_type_id | slot_value | +---------+----------------------------------+--------------------+ | 2316212 | 09FDBC8081294EF09D65F909E7FD9DE3 | à bout de souffle | +---------+----------------------------------+--------------------+ 1 row in set (0.05 sec) 表2的查询结果 mysql> select * from back_brace.slot_value where slot_type_id='09FDBC8081294EF09D65F909E7FD9DE3' and slot_value='a bout de souffle' ; +---------+----------------------------------+--------------------+ | id | slot_type_id | slot_value | +---------+----------------------------------+--------------------+ | 1109666 | 09FDBC8081294EF09D65F909E7FD9DE3 | a bout de souffle | | 1109667 | 09FDBC8081294EF09D65F909E7FD9DE3 | à bout de souffle | +---------+----------------------------------+--------------------+ 2 rows in set (2.65 sec) 囧了,竟然遇到上面的情况。。。。。。 但是通过查看对应的编码,是不同的: mysql> select hex('a') -> ; +----------+ | hex('a') | +----------+ | 61 | +----------+ 1 row in set (0.01 sec) mysql> select hex('à'); +-----------+ | hex('à') | +-----------+ | C3A0 | +-----------+ 1 row in set (0.01 sec) 接下来怀疑的是,表结构是否相同? 表1: slot_value | CREATE TABLE `slot_value` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `slot_type_id` varchar(36) COLLATE utf8_bin NOT NULL COMMENT 'slot类型id', `slot_value` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'slot值', PRIMARY KEY (`id`), UNIQUE KEY `slot_value_uniq_index` (`slot_type_id`,`slot_value`,`out_value`), KEY `slot_type_id` (`slot_type_id`), KEY `slot_value_type_index` (`type`), KEY `slot_value_type_id_index` (`slot_type_id`) ) ENGINE=InnoDB AUTO_INCREMENT=3762859 DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='保存slot类型对应的值信息表,一个slot类型可以有多个slot_value值' | 表2: | slot_value | CREATE TABLE `slot_value` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `slot_type_id` varchar(36) NOT NULL COMMENT 'slot类型id', `slot_value` varchar(255) NOT NULL COMMENT 'slot值', PRIMARY KEY (`id`), KEY `index_slot_type_id` (`slot_type_id`) ) ENGINE=InnoDB AUTO_INCREMENT=2309045 DEFAULT CHARSET=utf8 COMMENT='保存slot类型对应的值信息表,一个slot类型可以有多个slot_value值' 发现表1和表2的不同之处,在于建表语句的稍微不同,表1的建表语句中有 COLLATE=utf8_bin,表2没有这句。 将表2修改表结构,增加表1中有的COLLATE=utf8_bin,修改的方法如下 alter table slot_value CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin; 修改后表结构如下: slot_value | CREATE TABLE `slot_value` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `slot_type_id` varchar(36) COLLATE utf8_bin NOT NULL COMMENT 'slot类型id', `slot_value` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'slot值', PRIMARY KEY (`id`), KEY `index_slot_type_id` (`slot_type_id`) ) ENGINE=InnoDB AUTO_INCREMENT=2309045 DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='保存slot类型对应的值信息表,一个slot类型可以有多个slot_value值' 再在表2上执行查询语句: mysql> select * from slot_value where slot_type_id='09FDBC8081294EF09D65F909E7FD9DE3' and slot_value='à bout de souffle'; +---------+----------------------------------+--------------------+ | id | slot_type_id | slot_value | +---------+----------------------------------+--------------------+ | 1109667 | 09FDBC8081294EF09D65F909E7FD9DE3 | à bout de souffle | +---------+----------------------------------+--------------------+ 1 row in set (2.07 sec) mysql> select * from slot_value where slot_type_id='09FDBC8081294EF09D65F909E7FD9DE3' and slot_value='a bout de souffle'; +---------+----------------------------------+-------------------+ | id | slot_type_id | slot_value | +---------+----------------------------------+-------------------+ | 1109666 | 09FDBC8081294EF09D65F909E7FD9DE3 | a bout de souffle | +---------+----------------------------------+-------------------+ 1 row in set (2.34 sec) 完美解决问题。。。 但是为什么呢? 原来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类型的校对规则,这样不容易出错。 此外遇到这种情况,不用逐个改字段属性,而只要表格级别的collation就行了。 (对MySQL数据库中的varchar字段有效) 参考文档《MySQL 的 collation》:http://blog.csdn.net/xfsnow/article/details/2885948
深入的介绍,待续。。。