MySQL 大小寫敏感行為由作業系統文件系統、字符集校對規則、系統變量 lower_case_table_names 三者共同決定。本文系統梳理表名/列名/數據值三個層面的敏感規則,並給出跨平台遷移最佳實踐。
BINARY 屬性CREATE TABLE `name` (
`name` VARCHAR(10) BINARY -- 區分大小寫
);
效果:WHERE name='clip' 不匹配 'Clip'。
BINARY 操作符SELECT * FROM `name` WHERE BINARY name = 'Clip';
| 校對規則 | 大小寫敏感 | 典型場景 |
|---|---|---|
utf8_general_ci / utf8mb4_general_ci | 不敏感(_ci = case insensitive) | 通用業務,用戶名、郵箱去重 |
utf8_bin / utf8mb4_bin | 敏感(_bin = binary comparison) | 密碼驗證、Token、區分大小寫代碼 |
utf8mb4_0900_ai_ci (8.0 默認) | 不敏感 + 重音不敏感 | 多語言業務 |
lower_case_table_names| 作業系統 | 文件系統 | 默認 lower_case_table_names | 表名敏感度 |
|---|---|---|---|
| Windows | NTFS (不區分大小寫) | 1 | 不敏感,存儲為小寫 |
| Linux/Unix | ext4/xfs (區分大小寫) | 0 | 敏感,嚴格區分 |
| macOS | APFS/HFS+ (默認不區分) | 2 | 存儲按聲明大小寫,比較按小寫 |
lower_case_table_names 三種取值0:按聲明大小寫存儲,比較敏感(Linux 默認)。1:統一轉小寫存儲,比較不敏感(Windows 默認,推薦跨平台統一值)。2:按聲明大小寫存儲,比較轉小寫(macOS 默認)。# my.ini
[mysqld]
lower_case_table_names = 0
⚠ 風險:Windows 文件系統不區分大小寫,強制 0 會導致同名不同大小寫表無法共存,甚至數據損壞。生產環境強烈建議統一 1。
| 對象 | Linux | Windows |
|---|---|---|
| 庫名/表名 | 敏感 | 不敏感 |
| 表別名 | 敏感 | 不敏感 |
| 列名/列別名 | 不敏感 | 不敏感 |
用戶變量 @var | 敏感 | 不敏感 |
| 系統變量 | 不敏感 | 不敏感 |
user_order 而非 UserOrder)。lower_case_table_names=1 全環境統一(開發/測試/生產)。mysqldump --lower-case-table-names=1 強制小寫導出。hibernate.physical_naming_strategy、MyBatis mapUnderscoreToCamelCase 統一映射策略。SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA='db' AND TABLE_NAME != LOWER(TABLE_NAME); 發現大寫表名預警。大小寫敏感不是 Bug,是特性。統一規範、配置對齊、工具輔助,讓跨平台遷移「零驚喜」。