在 MySQL 中,預設的字符集校對規則通常是不區分大小寫的(如 utf8mb4_general_ci 中的 ci 代表 case-insensitive)。然而,許多業務場景——如用戶名驗證、密碼比對、代碼查找——要求嚴格區分大小寫。本文將系統介紹 MySQL 中實現大小寫敏感查詢的多種方法、原理差異與最佳實踐。
| 方法 | 語法範例 | 適用場景 | 效能影響 |
|---|---|---|---|
| BINARY 運算符 | WHERE name = BINARY 'Admin' | 臨時查詢、單次比對 | 無法使用索引,全表掃描 |
| BINARY() 函數 | WHERE BINARY(name) = 'Admin' | 列級強制區分 | 同 BINARY 運算符 |
| COLLATE 子句 | WHERE name COLLATE utf8mb4_bin = 'Admin' | 指定校對規則比對 | 可使用索引(若索引同校對) |
| 表/列定義校對 | name VARCHAR(50) COLLATE utf8mb4_bin | 永久性需求、核心業務欄位 | 最佳,索引天然支持 |
-- 查詢開發者為 'LYNN'(嚴格大小寫) SELECT id, developer FROM products WHERE developer != '' AND developer = BINARY 'LYNN'; -- 等價寫法 SELECT id, developer FROM products WHERE BINARY developer = 'LYNN';
原理:BINARY 將字符串轉換為二進制字符串,按字節值逐位比較,而非按字符集校對規則。
-- 使用二進制校對規則
SELECT * FROM users
WHERE username COLLATE utf8mb4_bin = 'Admin';
-- 或在建表時指定
CREATE TABLE users (
username VARCHAR(50) COLLATE utf8mb4_bin NOT NULL,
-- 其他欄位
);
優勢:若欄位定義或索引使用相同校對規則,查詢可利用索引,避免全表掃描。
| 字符集 | 二進制校對規則 | 不區分大小寫校對規則 |
|---|---|---|
| utf8mb4 | utf8mb4_bin | utf8mb4_general_ci / utf8mb4_0900_ai_ci |
| utf8 | utf8_bin | utf8_general_ci |
| latin1 | latin1_bin | latin1_swedish_ci |
| gbk | gbk_bin | gbk_chinese_ci |
-- 建立測試表
CREATE TABLE test_case (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) COLLATE utf8mb4_general_ci,
INDEX idx_name (name)
) ENGINE=InnoDB;
-- 插入 100 萬測試數據...
-- 1. 使用 BINARY - 無法使用索引 EXPLAIN SELECT * FROM test_case WHERE BINARY name = 'Test'; -- type: ALL, rows: 1000000 -- 2. 使用 COLLATE utf8mb4_bin - 同樣無法使用索引(欄位校對不同) EXPLAIN SELECT * FROM test_case WHERE name COLLATE utf8mb4_bin = 'Test'; -- type: ALL, rows: 1000000 -- 3. 欄位本身定義為 utf8mb4_bin - 可使用索引 ALTER TABLE test_case MODIFY name VARCHAR(50) COLLATE utf8mb4_bin; EXPLAIN SELECT * FROM test_case WHERE name = 'Test'; -- type: ref, rows: 1
COLLATE utf8mb4_binBINARY 或 COLLATE 子句utf8mb4_bin,模糊查詢用 COLLATE utf8mb4_general_ciALTER TABLE t ADD INDEX idx_name_bin (name COLLATE utf8mb4_bin)(MySQL 8.0+ 支持函數索引)Illegal mix of collationsutf8mb4_bin 按字節碼排序(數字→大寫→小寫),非自然語言排序utf8mb4_bin 下 'A' 和 'a' 可共存,utf8mb4_general_ci 下會衝突-- 欄位預設不區分大小寫,但特定查詢需區分 SELECT * FROM products WHERE name = 'iPhone' COLLATE utf8mb4_bin; -- 精確匹配 SELECT * FROM products WHERE name LIKE '%phone%' COLLATE utf8mb4_general_ci; -- 模糊匹配不區分大小寫 -- MySQL 8.0+ 函數索引優化 ALTER TABLE products ADD INDEX idx_name_bin ((name COLLATE utf8mb4_bin));
MySQL 大小寫敏感查詢的核心在於校對規則的選擇。對於高頻、核心業務欄位,建議在表結構設計階段就確定為二進制校對(utf8mb4_bin),從根源上解決效能與正確性問題;對於臨時需求,BINARY 關鍵字提供了最便捷的方案。理解字符集與校對規則的交互機制,是避免「明明數據存在卻查不到」這類靈異問題的關鍵。