MySQL 的大小寫敏感度取決於作業系統檔案系統、lower_case_table_names 參數、字符集校對規則。跨平台遷移(Windows ↔ Linux)是典型踩坑區。本文系統梳理規則、參數含義、實測驗證與最佳實踐。
| 值 | 行為 | 適用場景 |
|---|---|---|
| 0 | 按建表語句大小寫存儲文件名;查詢區分大小寫 | Linux 生產環境(預設) |
| 1 | 文件名統一轉小寫存儲;查詢**不區分**大小寫 | Windows/macOS 預設;跨平台兼容推薦 |
| 2 | 按建表語句大小寫存儲;查詢轉小寫比較(僅限不區分大小寫的檔案系統) | 極少用,Linux 下會自動降為 0 並報警告 |
my.cnf [mysqld] 區塊設置,需重啟生效SET GLOBAL lower_case_table_names=1 報錯 ERROR 1238 (HY000): read only variable=0) 遷移到 Windows(=1) 或反向,若表名大小寫不一致會導致 Table doesn't exist-- Linux, lower_case_table_names=0
CREATE TABLE TABLE1 (id INT);
SHOW TABLES; -- 顯示 TABLE1
SELECT * FROM TABLE1; -- OK
SELECT * FROM table1; -- ERROR 1146: Table 'test.table1' doesn't exist
-- 修改 my.cnf: lower_case_table_names=1, 重啟
SHOW TABLES; -- 顯示 table1 (文件系統實際為小寫)
SELECT * FROM TABLE1; -- OK (查詢轉小寫匹配)
SELECT * FROM table1; -- OK
_ci (Case Insensitive):不區分大小寫,如 utf8mb4_general_ci_cs (Case Sensitive):區分大小寫,如 utf8mb4_cs (8.0+)_bin (Binary):二進制比較,區分大小寫,且按字節碼排序,支援二進制數據-- 建表指定
CREATE TABLE t1 (name VARCHAR(10)) CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
CREATE TABLE t2 (name VARCHAR(10)) CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- 欄位級覆蓋
CREATE TABLE t3 (
name_ci VARCHAR(10) COLLATE utf8mb4_general_ci,
name_cs VARCHAR(10) COLLATE utf8mb4_bin
) CHARSET=utf8mb4;
-- 修改現有表
ALTER TABLE t1 CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
ALTER TABLE t1 MODIFY name VARCHAR(10) COLLATE utf8mb4_bin;
-- utf8mb4_bin (區分大小寫)
INSERT INTO t_bin VALUES ('A'),('a'),('B');
SELECT * FROM t_bin WHERE name LIKE 'a'; -- 僅返回 'a'
SELECT name, COUNT(*) FROM t_bin GROUP BY name; -- A:1, B:1, a:1
-- utf8mb4_general_ci (不區分)
INSERT INTO t_ci VALUES ('A'),('a'),('B');
SELECT * FROM t_ci WHERE name LIKE 'a'; -- 返回 'A', 'a'
SELECT name, COUNT(*) FROM t_ci GROUP BY name; -- a:2, B:1
-- BINARY 類型強制區分
ALTER TABLE t_ci MODIFY name VARCHAR(10) BINARY;
SELECT * FROM t_ci WHERE name LIKE 'A'; -- 僅返回 'A'
| 遷移方向 | 風險 | 解決方案 |
|---|---|---|
| Linux → Windows | Linux 表名大小寫混用,Windows 不區分,導致衝突 | 遷移前統一表名為小寫:RENAME TABLE OldName TO oldname |
| Windows → Linux | Windows 建表小寫,Linux 區分大小寫,應用若用大寫查詢報錯 | 1. 目標 Linux 設 lower_case_table_names=12. 或應用層統一 SQL 表名大小寫 |
| 雲托管 | 阿里云 RDS 預設 lower_case_table_names=1 | 遷移前確認參數一致,或使用 DTS 任務自動轉換 |
-- 1. 檢查參數
SHOW VARIABLES LIKE 'lower_case_table_names';
SHOW VARIABLES LIKE 'collation%';
-- 2. 掃描大小寫不一致表名
SELECT TABLE_NAME, TABLE_SCHEMA
FROM information_schema.TABLES
WHERE TABLE_SCHEMA NOT IN ('mysql','information_schema','performance_schema','sys')
AND TABLE_NAME != LOWER(TABLE_NAME);
-- 3. 檢查校對規則不一致欄位
SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, COLLATION_NAME
FROM information_schema.COLUMNS
WHERE COLLATION_NAME IS NOT NULL
AND COLLATION_NAME NOT LIKE '%_ci'
AND TABLE_SCHEMA NOT IN ('mysql','information_schema','performance_schema','sys');
snake_case)lower_case_table_names=1,消除跨平台差異_ci,精確匹配(如驗證碼、密碼哈希)用 _bin