• MySQL 查询不区分大小写的问题以及编码格式问题


    查询不区分大小写

    最近,在用SSH框架完成一个实践项目时,碰到了一个莫名其妙的Bug困扰了我好久,最后终于解决,记录如下。

    问题:同学在测试系统的时候突然发现,数据库保存的账户本来应该是admin,结果该同学用Admin账户居然登录成功了……

    ……EXM???这样也行?好吧,我还是查找这个Bug发生的原因吧。然后就是各种排查程序的过程,找来找去也没发现什么问题。终于想到,不用hql,自己写sql语句在数据库里面直接查询试试,结果果然发现了问题所在:

    select * from user where username = 'admin' and password = 'admin';
    select * from user where username = 'Admin' and password = 'admin';


    用上面的两条sql语句分表查询,出来的结果居然是一样的!……!!去搜索引擎搜索关键词:MySQL 查询 大小写,果然找到问题了!MySQL查询是不区分大小写的!这可真的是惊呆我了,虽然知道一般情况下,关键字是不区分大小写的,但是没想到连要查询的参数都是不区分大小写的!!再尝试下面的sql语句,果然还是一样的结果。

    select * from user where username = 'ADMIN' and password = 'admin';


    解决方案

    Mysql默认的字符检索策略:utf8_general_ci,表示不区分大小写;utf8_general_cs表示区分大小写,utf8_bin表示二进制比较,同样也区分大小写 。(注意:在Mysql5.6.10版本中,不支持utf8_genral_cs!!!!)

    创建表时,直接设置表的collate属性为utf8_general_cs或者utf8_bin;如果已经创建表,则直接修改字段的Collation属性为utf8_general_cs或者utf8_bin。

    -- 创建表:
    CREATE TABLE testt(
    id INT PRIMARY KEY,
    name VARCHAR(32) NOT NULL
    ) ENGINE = INNODB COLLATE =utf8_bin;
    -- 修改表结构的Collation属性
    ALTER TABLE TABLENAME MODIFY COLUMN COLUMNNAME VARCHAR(50) BINARY CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL;



    直接修改sql语句,在要查询的字段前面加上binary关键字即可。

    -- 在每一个条件前加上binary关键字
    select * from user where binary username = 'admin' and binary password = 'admin';
    
    -- 将参数以binary('')包围
    select * from user where username like binary('admin') and password like binary('admin');

    MySQL 编码格式

    在mysql中存在着各种utf8编码格式,如下:

    1)utf8_bin

    2)utf8_general_ci

    3)utf8_general_cs

    utf8_bin将字符串中的每一个字符用二进制数据存储,区分大小写。

    utf8_genera_ci不区分大小写,ci为case insensitive的缩写,即大小写不敏感。

    utf8_general_cs区分大小写,cs为case sensitive的缩写,即大小写敏感。

    现在假设执行如下命令:

    create table test_bin (
    
    name varchar(32) not null primary key,
    
    age int unsigned not null
    
    ) engine = InnoDB COLLATE=utf8_bin;

    以上命令能够执行成功。

    create table test_ci (
    
    name varchar(32) not null primary key,
    
    age int unsigned not null
    
    ) engine = InnoDB COLLATE=utf8_general_ci;

    以上命令能够执行成功。

    create table test_cs (
    
    name varchar(32) not null primary key,
    
    age int unsigned not null
    
    ) engine = InnoDB COLLATE=utf8_general_cs;

    在5.6.10版本中,以上命令执行失败,不支持utf8_genral_cs。

    insert into test_bin values('Alice', 18);

    以上命令能够执行成功。

    insert into test_bin values('alice', 18);

    以上命令能够执行成功,因为utf8_bin是以十六进制方式存储数据,两条记录的主键不重复。

    insert into test_ci values('Alice', 18);

    以上命令能够执行成功。

    insert into test_ci values('alily', 20);

    以上命令执行失败,因为utf8_general_ci不区分大小写,两条记录的主键重复。

  • 相关阅读:
    #include "stdafx.h" 错误?
    扩频技术
    求数组中只出现一次的数字(算法)
    1.3一摞烙饼的排序
    嵌套类
    企业级邮件服务软件推荐
    关于Linq To Sql中Detach方法和一个公共基类
    asp.net(c#) 将dbf转换为xls或wps,并将数据的列名改成中文;并判断本机是否安装office2003,2007和wps2007,2010
    一句代码解决IE8兼容问题(兼容性视图)
    asp.net(C#)套用模板操作Excel
  • 原文地址:https://www.cnblogs.com/ryanzheng/p/12309247.html
Copyright © 2020-2023  润新知