MySQL 預設字元集校對規則為 utf8_general_ci (Case Insensitive),導致 'A' = 'a' 為真,唯一索引視同重複值。本文提供查詢級、欄位級、表級三層面解決方案與原理深度解析。
| 後綴 | 全稱 | 大小寫敏感度 | 用途 |
|---|---|---|---|
| _bin | Binary | 敏感 (二進位比較) | 精確匹配、密碼、Token |
| _cs | Case Sensitive | 敏感 | 業務需區分大小寫 |
| _ci | Case Insensitive | 不敏感 (預設) | 一般文本搜尋、姓名、標題 |
| 物件 | 大小寫敏感度 | 說明 |
|---|---|---|
| SQL 關鍵字 (SELECT, FROM, WHERE) | 不敏感 | SeLeCt = SELECT |
| 資料庫名、表名 | 視作業系統而定 | Windows 不敏感;Linux 區分 (除非 HFS+ Mac) |
| 表別名 | 不敏感 | SELECT u.* FROM users u WHERE U.name = 'x' |
| 欄位別名 | 不敏感 | SELECT name AS n FROM users WHERE N = 'x' |
| 欄位值 (字串比較) | 取決於 COLLATE | 預設 _ci 不敏感;_bin/_cs 敏感 |
| 變數名 (@var, 系統變數) | 不敏感 | SET @X=1; SELECT @x; |
utf8mb4_general_ci (不敏感),符合多數業務直覺。COLLATE utf8mb4_bin。ALTER TABLE ... MODIFY COLUMN ... COLLATE utf8mb4_bin (線上 DDL 5.6+ 支援)。WHERE BINARY col = 'val'。COLLATE utf8_bin,導致所有文本搜尋變嚴格,使用者體驗下降。Windows (不敏感) 開發 → Linux (敏感) 部署時,表名大小寫不一致會導致 Table 'db.Users' doesn't exist。
解決:my.cnf 設定 lower_case_table_names=1 (強制小寫),或統一團隊命名規範 (全小寫 + 底線)。