MySQL 資料庫、表名的大小寫敏感性取決於底層檔案系統:Windows/Mac OS X (HFS+) 不敏感、Linux/Unix 敏感。這導致跨平台遷移、開發與生產環境不一致時頻發「表不存在」錯誤。本文系統分析機制、配置參數 lower_case_table_names 的三種模式與最佳實踐。
核心機制:檔案系統決定敏感性
| 平台 | 檔案系統 | 資料庫/表名敏感性 | 備註 |
| Windows | NTFS/FAT32 | 不敏感 | 建表存為小寫檔案 |
| Linux/Unix | ext4/xfs 等 | 敏感 | 大小寫嚴格區分 |
| Mac OS X | HFS+ (預設) | 不敏感 | 可掛載 UFS 卷啟用敏感 |
關鍵規則與易錯場景
- 同一查詢中大小寫必須一致:
SELECT * FROM my_table WHERE MY_TABLE.col=1; 會報錯,因 MySQL 內部以不同名稱解析。
- 欄位名、別名不敏感:
SELECT col_name FROM tbl 等同 SELECT COL_NAME。
- 表別名敏感:
SELECT * FROM t AS a WHERE a.id=1 OR A.id=2; 報錯,a ≠ A。
統一大小寫的參數:lower_case_table_names
| 值 | 行為 | 適用場景 | 預設值 |
| 0 | 保持原大小寫存儲,比較敏感 | Linux 生產環境、需區分大小寫 | Linux/Unix |
| 1 | **全部轉小寫存儲,比較不敏感** | 跨平台遷移、Windows 開發+Linux 生產、團隊習慣小寫 | Windows、Mac OS X |
| 2 | 保持原大小寫存儲,比較轉小寫(僅限不敏感檔案系統) | 極少用,兼容舊應用 | 無 |
修改方式與遷移步驟
方式一:啟動參數(臨時/測試)
./mysqld_safe --lower_case_table_names=1 &
方式二:配置檔永久生效(推薦)
# /etc/my.cnf 或 /etc/mysql/my.cnf
[mysqld]
lower_case_table_names=1
遷移現有資料庫的強制步驟(必須執行)
- 停止 MySQL:
systemctl stop mysqld
- 將資料目錄下所有資料庫目錄、表檔案重命名為小寫:
find /var/lib/mysql -depth -exec rename 'y/A-Z/a-z/' {} \;
- 修改
my.cnf 設定 lower_case_table_names=1
- 啟動 MySQL:
systemctl start mysqld
⚠️ 直接修改參數不重命名檔案會導致 MySQL 找不到表(檔案仍大寫、MySQL 找小寫),報錯 Table 'db.tbl' doesn't exist。
最佳實踐建議
- 團隊規約:全部小寫命名:資料庫、表、欄位、索引、別名統一小寫 + 底線分隔(snake_case),從源頭消除大小寫問題。
- 開發環境強制
lower_case_table_names=1:即使開發用 Mac/Windows,也模擬 Linux 行為,早期發現大小寫 Bug。
- ORM/遷移工具強制小寫:Flyway/Liquibase/Hibernate 設定
hibernate.physical_naming_strategy 輸出小寫。
- 跨平台遷移前驗證:
SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA='db' AND TABLE_NAME != LOWER(TABLE_NAME); 掃描非小寫表。
延伸閱讀
- MySQL MyISAM 表結構恢復
- MySQL 多表聯合查詢語法大全
- MySQL 表別名進階應用
- 三種 MySQL 建表亂碼解決方法
- 顯示 MYSQL 表資訊的方法