UPPER / LOWER 是什么
UPPER 与 LOWER 把字符串整体转为大写或小写,MySQL、PostgreSQL、SQL Server、Oracle 都提供。用途分两类:展示层统一格式,以及比较层做大小写无关匹配。后者要留意索引:把函数套在列上(如 WHERE LOWER(email) = …)会让普通索引失效,更稳妥的写法是存一列规范化后的值并建索引,或用表达式索引、不区分大小写的排序规则。
基本信息
| 适用平台 | 通用:MySQL 8.0 / PostgreSQL / SQL Server / Oracle |
|---|---|
| 语法 | UPPER(str)、LOWER(str) |
| NULL 行为 | 参数为 NULL 时返回 NULL |
| 受排序规则影响 | 转换结果取决于字符集与 collation,非 ASCII 语言的映射规则以 collation 为准 |
| 索引影响 | 在列上套 UPPER / LOWER 会让该列的普通索引失效 |
典型使用场景
- 展示统一:用户名、邮箱、国家代码统一大小写
- 大小写无关匹配:登录校验、白名单比对
- 格式校验:要求编码必须全大写或全小写
- 数据清洗与去重:把同一实体的不同写法统一后再比对
- 与 TRIM 组合生成规范化键,用于幂等判断
基础与匹配写法
基础与匹配写法
SELECT UPPER('abc') AS u, # ABC
LOWER('ABC') AS l; # abc
# 大小写无关匹配:把比较双方同时转换
SELECT id, email
FROM users
WHERE LOWER(email) = LOWER('User@Example.com');
# 更好:把规范化结果单独存一列并建索引,查询时不再套函数
ALTER TABLE users ADD COLUMN email_lower varchar(255) AS (LOWER(email)) STORED;
CREATE INDEX idx_users_email_lower ON users (email_lower);PostgreSQL 两种做法
PostgreSQL 两种做法
-- 表达式索引:查询表达式必须与索引表达式一致,才能复用
CREATE INDEX idx_users_email_lower ON users (lower(email));
SELECT id, email FROM users WHERE lower(email) = lower('User@Example.com');
-- citext 类型:列本身大小写不敏感,查询不必改写
CREATE EXTENSION IF NOT EXISTS citext;
ALTER TABLE users ALTER COLUMN email TYPE citext;匹配方式对照
| 做法 | 优点 | 代价 |
|---|---|---|
| LOWER(列) = LOWER(值) | 写法直白 | 列上套函数,普通索引失效 |
| lower(email) 表达式索引 | 查询能走索引 | 仅 PG 等支持,表达式须与查询一致 |
| 生成列 STORED + 索引 | MySQL 可用,查询简单 | 额外占用存储空间 |
| citext / 不区分大小写 collation | 列语义清晰 | 依赖数据库类型或排序规则,迁移需注意 |
大小写敏感度常由排序规则决定:MySQL 的 utf8mb4_general_ci 本身不区分大小写,等值查询自动忽略差异;而 utf8mb4_bin 或 PostgreSQL 的默认 collation 会区分,迁移环境前先确认这一项。
在 PostgreSQL 里建了 lower(email) 的表达式索引,查询却写成 UPPER(email) = …,索引无法复用;索引表达式与查询表达式必须一致。