Mysql通过一个限制条件,查出多条不同的记录

表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 |
+---------+----------------------------------+-------------------+
| | 09FDBC8081294EF09D65F909E7FD9DE3 | a bout de souffle |
+---------+----------------------------------+-------------------+
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 |
+---------+----------------------------------+--------------------+
| | 09FDBC8081294EF09D65F909E7FD9DE3 | à bout de souffle |
+---------+----------------------------------+--------------------+
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 |
+---------+----------------------------------+--------------------+
| | 09FDBC8081294EF09D65F909E7FD9DE3 | a bout de souffle |
| | 09FDBC8081294EF09D65F909E7FD9DE3 | à bout de souffle |
+---------+----------------------------------+--------------------+
rows in set (2.65 sec) 囧了,竟然遇到上面的情况。。。。。。
但是通过查看对应的编码,是不同的:
mysql> select hex('a')
-> ;
+----------+
| hex('a') |
+----------+
| |
+----------+
row in set (0.01 sec) mysql> select hex('à');
+-----------+
| hex('à') |
+-----------+
| C3A0 |
+-----------+
row in set (0.01 sec) 接下来怀疑的是,表结构是否相同?
表1:
slot_value | CREATE TABLE `slot_value` (
`id` bigint() NOT NULL AUTO_INCREMENT,
`slot_type_id` varchar() COLLATE utf8_bin NOT NULL COMMENT 'slot类型id',
`slot_value` varchar() 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= DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='保存slot类型对应的值信息表,一个slot类型可以有多个slot_value值' | 表2:
| slot_value | CREATE TABLE `slot_value` (
`id` bigint() NOT NULL AUTO_INCREMENT,
`slot_type_id` varchar() NOT NULL COMMENT 'slot类型id',
`slot_value` varchar() NOT NULL COMMENT 'slot值',
PRIMARY KEY (`id`),
KEY `index_slot_type_id` (`slot_type_id`)
) ENGINE=InnoDB AUTO_INCREMENT= 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() NOT NULL AUTO_INCREMENT,
`slot_type_id` varchar() COLLATE utf8_bin NOT NULL COMMENT 'slot类型id',
`slot_value` varchar() COLLATE utf8_bin NOT NULL COMMENT 'slot值',
PRIMARY KEY (`id`),
KEY `index_slot_type_id` (`slot_type_id`)
) ENGINE=InnoDB AUTO_INCREMENT= 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 |
+---------+----------------------------------+--------------------+
| | 09FDBC8081294EF09D65F909E7FD9DE3 | à bout de souffle |
+---------+----------------------------------+--------------------+
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 |
+---------+----------------------------------+-------------------+
| | 09FDBC8081294EF09D65F909E7FD9DE3 | a bout de souffle |
+---------+----------------------------------+-------------------+
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

深入的介绍,待续。。。

上一篇:java List 排序


下一篇:逻辑卷(lv)管理(LVM)