zoukankan      html  css  js  c++  java
  • 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不区分大小写,两条记录的主键重复。

  • 相关阅读:
    POJ2253 Frogger
    搜索专题(复习)
    机器学习资料整理
    51nod 1873 初中的算术
    Canny检测理解和Matlab实现
    Floyd+限制路径步数(快速幂优化)
    bitset优化背包问题
    Educational Codeforces Round 44 (Rated for Div. 2)
    BZOJ 3224 SBT 普通平衡树
    本科课程大数据基础
  • 原文地址:https://www.cnblogs.com/ryanzheng/p/12309247.html
Copyright © 2011-2022 走看看