MySQL中应显式用UPPER()/LOWER()统一大小写比较,但会失效普通索引;PostgreSQL推荐ILIKE或LOWER()配合表达式索引;SQL Server可用COLLATE临时覆盖排序规则;跨库应统一用LOWER()加参数化及对应函数索引。

MySQL 中用 UPPER() 或 LOWER() 统一大小写再比较
MySQL 默认的字符串比较行为取决于字段的 collation。如果列是 utf8mb4_general_ci 或 utf8mb4_0900_as_cs 以外的 _ci(case-insensitive)结尾的校对规则,WHERE 中直接写 name = 'Alice' 就已不区分大小写——但这是隐式行为,不可靠,尤其当表结构变更或迁移到其他环境时容易出错。稳妥做法是显式转换:
- 统一转大写:
WHERE UPPER(name) = UPPER('alice') - 统一转小写:
WHERE LOWER(name) = LOWER('Alice') - 注意:对字段用函数会阻止该列上普通索引的使用,查询变慢;若高频执行,建议改用
COLLATE utf8mb4_0900_as_cs(不推荐)或建函数索引(MySQL 8.0.13+):CREATE INDEX idx_name_lower ON users ((LOWER(name)))
PostgreSQL 中用 ILIKE 或 LOWER() 配合索引
PostgreSQL 默认区分大小写,= 操作符严格比对 ASCII 值。ILIKE 是最直接的替代方案,语义清晰且支持模式匹配:
- 精确匹配:
WHERE name ILIKE 'alice' - 模糊匹配:
WHERE name ILIKE '%ali%' - 若需走索引,不能依赖
ILIKE(除非用pg_trgm扩展),更可靠的是:WHERE LOWER(name) = LOWER('Alice'),并配合表达式索引:CREATE INDEX idx_users_lower_name ON users (LOWER(name)) - 避免写
name::text ILIKE '...'——类型强制转换多余,还可能干扰计划器
SQL Server 中用 COLLATE 子句临时指定排序规则
SQL Server 的大小写敏感性由数据库/列级 collation 决定,但你可以在单条查询中覆盖它,无需修改表结构:
- 临时设为不区分大小写:
WHERE name COLLATE SQL_Latin1_General_CP1_CI_AS = 'Alice' -
CI表示 case-insensitive,AS表示 accent-sensitive;常见组合还有_CI_AI(忽略重音) - 注意:
COLLATE只能用于比较操作符右侧或两侧之一,不能写成name COLLATE ... = 'Alice' COLLATE ...——两边 collation 不兼容会报错Cannot resolve collation conflict - 如果列本身是
_CS(case-sensitive),又不想改 schema,这是最轻量的解法;但频繁使用可能影响执行计划稳定性
跨数据库可移植写法:始终用 LOWER() + 参数化
如果你的代码要适配多种数据库(比如 ORM 动态生成 SQL 或迁移脚本),避免依赖方言特性。最稳妥的通用策略是:
- 统一用
LOWER(column)和LOWER(?)(参数占位符)配对比较 - 确保参数传入前不额外做大小写处理,交给 SQL 层统一做
- 在应用层建索引时同步创建函数索引(如 PostgreSQL)、计算列索引(SQL Server)或虚拟列索引(MySQL),否则性能会明显下降
- 别指望
LIKE自动忽略大小写——它和=一样受 collation 控制,在 PostgreSQL 和默认 SQL Server 下都区分大小写
LOWER() 就全表扫描。先 explain,再加索引,别凭感觉上线。

















