首先解释一下问题,大小写敏感分为两个层面:
- varchar类型的值,insert 和 select 的结果是否是大小写敏感的?
- varchar类型的数据在比较的时候是否是大小写敏感的?
insert 和get 是否大小写敏感
通过查询mysql的配置参数,可以获得mysql本身对于varchar
类型的字符存储是否是大小写敏感的:show Variables like '%lower_case_table_names'
,结果是
0
表示大小写敏感;1
表示大小写不敏感;
例如,创建一个数据库:
CREATE TABLE `test` (
`name` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
使用的排序规则collation=utf8_general_ci
。
插入数据:
insert into test values ('a');
insert into test values ('A');
查询数据在mysql中存储的ascii码:
mysql> select name, ASCII(name) from test;
+------+-------------+
| name | ASCII(name) |
+------+-------------+
| a | 97 |
| A | 65 |
+------+-------------+
2 rows in set (0.00 sec)
ASCII
函数返回字符串最左边字符的ascii码。
存储在数据库中的字符ascii码是不同的,所以区分了大小写。
varchar类型的数据比较是否是大小写敏感
常见的进行数据比较的场景如:
- 使用了比较运算符,$>=, >, =, <, <=$
- 排序操作,
group
,order
- like操作
在数据比较时,
- 非字节类型数据,如
CHAR
,VARCHAR
,TEXT
类型,数据比较会使用数据的排序规则(collation配置); - 字节类型数据,如
BINARY
,VARBINARY
,BLOB
类型,数据比较二进制的每个字节; - 非字节类型数据和字节类型数据比较会按照字节类型数据比较规则进行。
数据库的默认编码一般是charset=utf8
排序规则collation=utf8_general_ci
,那么在比较的时候,非字节类型字符串就是大小写不敏感的。如果使用了类似LIKE 'a%'
,会将a%
和A%
全部获取出来。
utf8_bin
将字符串中的每一个字符用二进制数据存储,区分大小写。utf8_genera_ci
不区分大小写,ci为case insensitive的缩写,即大小写不敏感。utf8_general_cs
区分大小写,cs为case sensitive的缩写,即大小写敏感。
如果希望字符串比较时是大小写敏感的,那么需要修改排序规则。
日常使用情况总结
如果需要在查询中对非字符类型的数据进行比较操作,那么建议将database的排序规则改为utf8_bin
,这样改database下的所有数据库均继承于database的collation支持排序。 如果仅仅是一个表需要支持,那么仅需要更新一个表的collection;甚至仅需要更改一个column的排序规则,也可以更新列的collection。