zoukankan      html  css  js  c++  java
  • 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        |
    +---------+----------------------------------+-------------------+
    | 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

    深入的介绍,待续。。。

  • 相关阅读:
    15-07-23 HTML--标签
    15-07-22 数据库--存储过程、触发器
    15-07-19数据库练习题答案
    15-07-17 数据库练习题
    15-07-20 数据库--索引视图编程
    15-07-17 数据库--高级查询
    c#语句
    SQL 触发器
    SQL 存储过程
    SQL 循环语句
  • 原文地址:https://www.cnblogs.com/zhzhang/p/6895636.html
Copyright © 2011-2022 走看看