MySQL查询大小写不敏感异常原因咨询(Django场景)
为什么你的MySQL查询会大小写不敏感?
嘿,这个问题其实是MySQL的**字符集排序规则(collation)**在背后起作用,和你默认认知的“MySQL查询大小写敏感”不一样,我给你拆解清楚:
首先,MySQL的大小写敏感性根本不是全局固定的,而是由表/列使用的排序规则决定的:
- 带
_ci后缀的排序规则(比如utf8mb4_general_ci、latin1_swedish_ci)是大小写不敏感的,这也是很多MySQL实例的默认配置。用这种规则时,'shivam'和'ShivaM'会被判定为相等,所以你那两条SQL查出来结果完全一致。 - 而带
_cs后缀的是大小写敏感规则,_bin后缀的是二进制严格匹配规则,这两种才会严格区分大小写。
- 带
再说说Django的影响:Django创建表时,默认会继承数据库的默认排序规则。如果你的MySQL实例默认用的是
_ci类规则,那auth_user表的username列自然就用上了这个规则,所以直接写原生SQL查询时会忽略大小写——哪怕你平时习惯用Django的icontains/iexact,其实底层要么是利用了这个排序规则,要么是做了转小写处理,但本质和直接SQL查询的效果一致。
怎么验证这个规则?
你可以跑这两条SQL确认一下:
- 查看整个
auth_user表的排序规则:
SHOW CREATE TABLE auth_user;
看输出里的COLLATE字段,比如utf8mb4_general_ci就是典型的不敏感规则。
- 单独查看
username列的排序规则:
SELECT column_name, collation_name FROM information_schema.columns WHERE table_name = 'auth_user' AND column_name = 'username';
如果想改成大小写敏感怎么办?
有两种可行方式:
- 直接修改MySQL列的排序规则:
-- 用二进制匹配(严格区分大小写) ALTER TABLE auth_user MODIFY COLUMN username VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; -- 或者MySQL 8.0+可以用专门的大小写敏感规则 ALTER TABLE auth_user MODIFY COLUMN username VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_as_cs;
- 在Django模型层配置(Django 2.2+支持):
给username字段加上db_collation参数,然后执行迁移:
from django.db import models class AuthUser(models.Model): username = models.CharField(max_length=255, db_collation='utf8mb4_bin') # 其他字段保持不变
最后补充一句:你平时用的icontains和iexact,不管底层排序规则如何,都会生成大小写不敏感的查询逻辑,但如果底层已经是_ci规则,那直接用=和这些方法的效果就会完全一致啦。
内容的提问来源于stack exchange,提问作者user9754369
相关产品推荐
相关产品推荐

