問題背景
MySQL 預設不區分大小寫(如 'A' = 'a'),Oracle 則區分。唯一約束列插入 'A' 和 'a' 會報重複鍵錯誤。
解決方案對比
方案一:查詢級強制區分(BINARY 關鍵字)
SELECT * FROM usertable WHERE BINARY id = 'AAMkADExM2M5NjQ2LWUzYzctNDFkMC1h';
方案二:建表時欄位級設置
-- 方式 1:BINARY 屬性
CREATE TABLE usertable (
id VARCHAR(32) BINARY,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- 方式 2:指定 COLLATE(推薦,更標準)
CREATE TABLE usertable (
id VARCHAR(32) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
COLLATE 規則速查
| 後綴 | 含義 | 大小寫敏感 |
_bin | 二進制比較 | ✅ 是 |
_cs | Case Sensitive | ✅ 是 |
_ci | Case Insensitive | ❌ 否(預設) |
MySQL 大小寫敏感度總覽
| 對象 | 敏感度 | 說明 |
| SQL 關鍵字 | 不敏感 | SELECT = select = SeLeCt |
| 標識符(庫/表名) | 視作業系統 | Windows 不敏感,Linux 區分(HFS+ 的 Mac 除外) |
| 表別名 | 不敏感 | m = M |
| 列別名 | 不敏感 | uname = UName |
| 字符串比較 | 取決於 COLLATE | 預設 utf8_general_ci 不敏感 |
最佳實踐建議
- 新表設計階段直接指定
COLLATE utf8mb4_bin 或 utf8_bin
- 既有表修改:
ALTER TABLE t MODIFY c VARCHAR(32) COLLATE utf8_bin;
- 查詢臨時需求用
BINARY,避免全表掃描失去索引優勢
- 統一團隊規範:庫/表/欄位命名全小寫 + 下劃線
注意: utf8mb4 支援 Emoji,新專案優先選擇 utf8mb4_bin / utf8mb4_general_ci。