收起左侧

    [其他教程] MySQL中查询的有关英文字母大小写问题的分析

    16
    回复
    2512
    查看
    [复制链接]

    管理员

    3374

    主题

    3421

    帖子

    1万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    15115
    发表于 2015-9-18 19:43:00 | 显示全部楼层 |阅读模式
    mysql数据库在做查询时候,有时候是英文字母大小写敏感的,有时候又不是的,主要是由mysql的字符校验规则的设置决定的,通常默认是不支持的大小写字母敏感的。
    1. 什么是字符集和校验规则?
    字符集是一套符号和编码。校对规则是在字符集内用于比较字符的一套规则。任何一个给定的字符集至少有一个校对规则,它可能有几个校对规则。要想列出一个字符集的校对规则,使用SHOW COLLATION语句。

    校对规则一般有这些特征:
        两个不同的字符集不能有相同的校对规则。
        每个字符集有一个默认校对规则。例如,utf8默认校对规则是utf8_general_ci。
        存在校对规则命名约定:它们以其相关的字符集名开始,通常包括一个语言名,并且以_ci(大小写不敏感)、_cs(大小写敏感)或_bin(二元)结束。
    2. 不同级别的字符集和校验规则可控制大小写敏感
    MySQL5.1在同一台服务器、同一个数据库或甚至在同一个表中使用不同字符集或校对规则来混合定义字符串。字符集和校对规则有4个级别的默认设置:服务器级、数据库级、表级和连接级。
    2.1服务器级
    MySQL按照如下方法确定服务器字符集和服务器校对规则:
    (1)修改配置文件/etc/my.cnf
    在[mysqld]下添加:collation_server = utf8_bin
    重启实例

    更改服务器级的校验规则(collation_server )后,数据库校验规则(collation_collation)默认会继承服务器级的。
    注意:
    这个只适用于在重新启动之后, 新建的库,已存在的库不受影响.
    同样的, 即使库的校验规则改了,已经存在的表不受修改影响;
    同理与已经存在的列...
    [color=white !important][backcolor=rgb(108, 226, 108) !important]
    [color=white !important]?

    01

    02

    03

    04

    05

    06

    07

    08

    09

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    mysql> create database yutest0;
    Query OK, 1 row affected (0.00 sec)
    mysql> use yutest0;
    Database changed
    mysql> create table t1 (name varchar(10));
    Query OK, 0 rows affected (0.01 sec)
    mysql> insert into t1 values('AAA');
    Query OK, 1 row affected (0.00 sec)
    mysql> insert into t1 values('aaa');
    Query OK, 1 row affected (0.01 sec)
    mysql> select * from t1;
    +------+
    | name |
    +------+
    | AAA |
    | aaa |
    +------+
    2 rows in set (0.00 sec)
    mysql> select * from t1 where name='aaa';
    +------+
    | name |
    +------+
    | aaa |
    +------+
    1 row in set (0.00 sec)




    可以看出,在服务器级进行相应的校对规则设置,查询大小写敏感。
    (2)当服务器启动时根据有效的选项设置
    当启动mysqld时,根据使用的初始选项设置来确定服务器字符集和校对规则。
    shell> mysqld --character-set-server=latin1 --collation-server=latin1_swedish_ci
    2.2数据库级
    MySQL这样选择数据库字符集和数据库校对规则:
        如果指定了character set X和collate Y,那么采用字符集X和校对规则Y。
        如果指定了character set X而没有指定collate Y,那么采用character set X和character set X的默认校对规则。
        否则,采用服务器字符集和服务器校对规则。
    (1)修改配置文件/etc/my.cnf
    进行了两组测试:
    1) 在[mysqld]下添加:
    [color=white !important][backcolor=rgb(108, 226, 108) !important]
    [color=white !important]?

    1

    2

    collation_server = utf8_bin
    collation_database = utf8_bin




    2) 在[mysqld]下添加:
    [color=white !important][backcolor=rgb(108, 226, 108) !important]
    [color=white !important]?

    1

    collation_database = utf8_bin




    重启实例,两组都不能正常启动,错误信息如下:

    可见,my.cnf配置文件中不支持设置collation_database 变量。
    (2)创建数据库时设置数据库校验规则
    [color=white !important][backcolor=rgb(108, 226, 108) !important]
    [color=white !important]?

    01

    02

    03

    04

    05

    06

    07

    08

    09

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    mysql> create database yutest default character set utf8 collate utf8_bin;
    Query OK, 1 row affected (0.00 sec)
    mysql> show variables like 'collation_%';
    +----------------------+-----------------+
    | Variable_name    | Value      |
    +----------------------+-----------------+
    | collation_connection | utf8_general_ci |
    | collation_database  | utf8_bin    |
    | collation_server   | utf8_general_ci |
    +----------------------+-----------------+
    3 rows in set (0.00 sec)
    mysql> select * from t1;
    +------+
    | name |
    +------+
    | ABC |
    | abc |
    +------+
    2 rows in set (0.00 sec)
    mysql> select * from t1 where name='abc';
    +------+
    | name |
    +------+
    | abc |
    +------+
    1 row in set (0.01 sec)




    可以看出,在数据库级进行相应的校对规则设置,查询大小写敏感。
    2.3表级
    MySQL按照下面的方式选择表字符集和校对规则:
        如果指定了character set X和collate Y,那么采用character set X和collate Y。
        如果指定了character set X而没有指定collate Y,那么采用character set X和character set X的默认校对规则。
        否则,采用数据库字符集和服务器校对规则。
    在创建表时设置表级校验规则:
    [color=white !important][backcolor=rgb(108, 226, 108) !important]
    [color=white !important]?

    01

    02

    03

    04

    05

    06

    07

    08

    09

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    mysql> create database yutest2;
    Query OK, 1 row affected (0.01 sec)
    mysql> use yutest2;
    Database changed
    mysql> create table t1(name varchar(10))
      -> default character set utf8 collate utf8_bin;
    Query OK, 0 rows affected (0.01 sec)
    mysql> insert into t1 values('ABC');
    Query OK, 1 row affected (0.00 sec)
    mysql> insert into t1 values('abc');
    Query OK, 1 row affected (0.00 sec)
    mysql> show variables like 'collation_%';
    +----------------------+-----------------+
    | Variable_name    | Value      |
    +----------------------+-----------------+
    | collation_connection | utf8_general_ci |
    | collation_database  | utf8_general_ci |
    | collation_server   | utf8_general_ci |
    +----------------------+-----------------+
    3 rows in set (0.00 sec)
    mysql> select * from t1;
    +------+
    | name |
    +------+
    | ABC |
    | abc |
    +------+
    2 rows in set (0.00 sec)
    mysql> select * from t1 where name='abc';
    +------+
    | name |
    +------+
    | abc |
    +------+
    1 row in set (0.00 sec)




    可以看出,在表级进行相应的校对规则设置,查询大小写敏感。
    2.4 连接级
    考虑什么是一个“连接”:它是连接服务器时所作的事情。客户端发送SQL语句,例如查询,通过连接发送到服务器。服务器通过连接发送响应给客户端,例如结果集。对于客户端连接,这样会导致一些关于连接的字符集和校对规则的问题,这些问题均能够通过系统变量来解决:
    [color=white !important][backcolor=rgb(108, 226, 108) !important]
    [color=white !important]?

    01

    02

    03

    04

    05

    06

    07

    08

    09

    10

    11

    12

    13

    14

    mysql> show variables like 'character%';
    +--------------------------+----------------------------+
    | Variable_name      | Value           |
    +--------------------------+----------------------------+
    | character_set_client   | utf8            |
    | character_set_connection | utf8            |
    | character_set_database  | utf8            |
    | character_set_filesystem | binary           |
    | character_set_results  | utf8            |
    | character_set_server   | utf8            |
    | character_set_system   | utf8            |
    | character_sets_dir    | /usr/share/mysql/charsets/ |
    +--------------------------+----------------------------+
    8 rows in set (0.00 sec)




        当查询离开客户端后,在查询中使用哪种字符集?
    服务器使用character_set_client变量作为客户端发送的查询中使用的字符集。
        服务器接收到查询后应该转换为哪种字符集?
    转换时,服务器使用character_set_connection和collation_connection系统变量。它将客户端发送的查询从character_set_client系统变量转换到character_set_connection。
        服务器发送结果集或返回错误信息到客户端之前应该转换为哪种字符集?
    character_set_results变量指示服务器返回查询结果到客户端使用的字符集。包括结果数据,例如列值和结果元数据(如列名)。
    3. 创建数据库表时大小写不敏感,仍然有方法在查询时区分大小写
    3.1 在SQL语句中使用collate
    使用collate子句,能够为一个比较覆盖任何默认校对规则。collate可以用于多种SQL语句中,比如where,having,group by,order by,as,聚合函数。
    [color=white !important][backcolor=rgb(108, 226, 108) !important]
    [color=white !important]?

    01

    02

    03

    04

    05

    06

    07

    08

    09

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    mysql> select * from t1 where name collate utf8_bin = 'ABC';
    +------+
    | name |
    +------+
    | ABC |
    +------+
    1 row in set (0.00 sec)
    mysql> select * from t1 where name = 'ABC';
    +------+
    | name |
    +------+
    | ABC |
    | Abc |
    | abc |
    +------+
    3 rows in set (0.00 sec)
    mysql> select * from t1;
    +------+
    | name |
    +------+
    | ABC |
    | Abc |
    | abc |
    +------+
    3 rows in set (0.00 sec)




    3.2 binary操作符
    binary操作符是collate子句的一个速记符。binary 'x'等价与'x' collate y,这里y是字符集'x'二元校对规则的名字。每一个字符集有一个二元校对规则。例如,latin1字符集的二元校对规则是latin1_bin,因此,如果列a是字符集latin1,以下两个语句有相同效果:
    [color=white !important][backcolor=rgb(108, 226, 108) !important]
    [color=white !important]?

    01

    02

    03

    04

    05

    06

    07

    08

    09

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    select * from t1 order by binary a;
    select * from t1 order by a collate latin1_bin;
    mysql> select * from t1 where binary name = 'ABC';
    +------+
    | name |
    +------+
    | ABC |
    +------+
    1 row in set (0.00 sec)
    mysql>
    mysql> select * from t1 where name = 'ABC';
    +------+
    | name |
    +------+
    | ABC |
    | Abc |
    | abc |
    +------+
    3 rows in set (0.00 sec)




    温馨提示:
    1、本站所有信息都来源于互联网有违法信息与本网站立场无关。
    2、当有关部门,发现本论坛有违规,违法内容时,可联系站长删除,否则本站不承担任何责任。
    3、当政府机关依照法定程序要求披露信息时,论坛均得免责。
    4、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
    5、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除并致以最深的歉意
    6、如果使用本帖附件,本站程序只提供学习使用,请24小时内删除!使用者搭建运营触犯法律,违法,违规,本站不承担任何责任。
    回复

    使用道具 举报

    注册会员

    0

    主题

    8

    帖子

    71

    积分

    注册会员

    Rank: 2

    积分
    71
    发表于 2015-9-18 19:24:46 | 显示全部楼层
    很不错
    回复 支持 反对

    使用道具 举报

    注册会员

    0

    主题

    15

    帖子

    83

    积分

    注册会员

    Rank: 2

    积分
    83
    发表于 2015-9-18 19:21:18 | 显示全部楼层
    很好哦
    回复 支持 反对

    使用道具 举报

    注册会员

    0

    主题

    8

    帖子

    71

    积分

    注册会员

    Rank: 2

    积分
    71
    发表于 2015-9-18 19:41:44 | 显示全部楼层
    牛牛牛牛牛牛牛牛牛
    回复 支持 反对

    使用道具 举报

    注册会员

    0

    主题

    16

    帖子

    95

    积分

    注册会员

    Rank: 2

    积分
    95
    发表于 2015-9-18 19:48:00 | 显示全部楼层
    支持,赞一个支持,赞一个支持,赞一个支持,赞一个支持,赞一个支持,赞一个支持,赞一个支持,赞一个
    回复 支持 反对

    使用道具 举报

    注册会员

    0

    主题

    11

    帖子

    86

    积分

    注册会员

    Rank: 2

    积分
    86
    发表于 2015-9-18 19:03:19 | 显示全部楼层
    鼎力支持!!
    回复 支持 反对

    使用道具 举报

    注册会员

    0

    主题

    13

    帖子

    95

    积分

    注册会员

    Rank: 2

    积分
    95
    发表于 2015-9-18 19:43:01 | 显示全部楼层
    真心顶
    回复 支持 反对

    使用道具 举报

    注册会员

    0

    主题

    17

    帖子

    95

    积分

    注册会员

    Rank: 2

    积分
    95
    发表于 2015-9-18 19:25:49 | 显示全部楼层
    牛牛牛牛牛牛牛牛牛
    回复 支持 反对

    使用道具 举报

    注册会员

    0

    主题

    14

    帖子

    91

    积分

    注册会员

    Rank: 2

    积分
    91
    发表于 2015-9-18 19:50:49 | 显示全部楼层
    这是 真的可以的吗?
    回复 支持 反对

    使用道具 举报

    注册会员

    0

    主题

    20

    帖子

    106

    积分

    注册会员

    Rank: 2

    积分
    106
    发表于 2015-9-18 19:29:13 | 显示全部楼层
    我最不喜欢发表无意义的回帖,但是为了源码我也只能这样了!
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    在线客服
    热线电话

    微信扫一扫
    专注源码分享6年
    全国免费热线电话

    400-225-995

    周一至周日9:00-23:00

    反馈建议

    a5887776@163.com 在线QQ咨询

    Powered by Discuz! X3.4 Licensed © 2001-2013 Comsenz Inc.