表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
深入的介紹,待續。。。