MySQL 的資料庫與表名大小寫敏感性由底層作業系統檔案系統決定,這導致跨平台部署時極易踩坑。本文深度解析機制原理、平台差異、配置控制參數與最佳命名規範,助你構建跨平台相容的資料庫架構。
MySQL 將每個資料庫對應一個目錄,每張表對應一或多個檔案(.frm 定義、.ibd/.MYD 資料、.MYI 索引)。因此:
mytable、MYTABLE、MyTable 指向同一張表-- 錯誤:Windows 下也會失敗
SELECT * FROM my_table WHERE MY_TABLE.col = 1;
-- ERROR 1146: Table 'test.MY_TABLE' doesn't exist
原因:查詢解析器在同一語句內對同一表的不同別名視為不同物件。
-- 錯誤:別名 'a' 與 'A' 不同
SELECT col_name FROM tbl_name AS a WHERE a.col_name = 1 OR A.col_name = 2;
-- ERROR 1054: Unknown column 'A.col_name'
UserOrderSELECT * FROM userorder → Table doesn't exist此參數控制 MySQL 內部儲存與比對時的大小寫處理:
| 值 | 行為 | 適用場景 | 備註 |
|---|---|---|---|
| 0 | 保留原始大小寫儲存,比對區分大小寫 | Linux/Unix 生產環境(預設) | 檔案系統需支援大小寫敏感 |
| 1 | **全部轉小寫儲存**,比對不區分大小寫 | Windows / macOS / 跨平台相容 | Windows 預設值;4.0.2+ 也適用資料庫名 |
| 2 | 保留原始大小寫儲存,**比對轉小寫** | 特殊需求(極少用) | 僅限不區分大小寫檔案系統 |
# 停止服務
/etc/init.d/mysql stop
# 或
systemctl stop mysqld
# 啟動帶參數
mysqld_safe --lower_case_table_names=1 &
[mysqld]
lower_case_table_names=1
⚠️ 關鍵警告:修改此參數**必須**先將現有所有表名轉為小寫,否則 MySQL 找不到原表(檔案系統仍是舊大小寫檔名)。
user_order、order_item、sys_configmall_order、mall_useruser_id、created_atidx_user_email、fk_order_user| 階段 | 檢查項目 | 工具/指令 |
|---|---|---|
| 開發規範 | 命名規範文檔化、Code Review 攔截 | ESLint/SQLFluff 自訂規則 |
| 建表腳本 | 所有識別符小寫、反引號包裹 | mysqldump --no-data 檢視 |
| 遷移測試 | Windows→Linux 導入驗證查詢 | 測試環境雙平台部署 |
| 生產配置 | lower_case_table_names=1 統一 | Ansible/Terraform 批量下發 |
| 監控告警 | 異常大小寫查詢攔截 | ProxySQL 規則 / 慢查詢分析 |
RENAME TABLE `OldName` TO `oldname` 逐表重命名(或寫腳本批量)mysqldump --lower-case-table-names=1lower_case_table_names=1 後導入CREATE VIEW usertable AS SELECT * FROM `UserTable`MySQL 大小寫敏感性本質是檔案系統特性投射。**統一配置 lower_case_table_names=1` + 全域小寫命名規範** 是跨平台零成本、零風險的最佳方案。建議在專案啟動日即納入架構規範,避免後期遷移付出巨大代價。