mysql大小写敏感需分两层:表名/库名由操作系统和lower_case_table_names参数决定,字段值比较则完全取决于collation,与lower_case_table_names无关。

MySQL是否大小写敏感,不能一概而论——它分两层:表名/库名的大小写行为由操作系统和lower_case_table_names决定;字段值的比较是否区分大小写,则完全取决于字符集的COLLATION,跟lower_case_table_names毫无关系。搞混这两者,90%的“大小写问题”都查偏了方向。
Linux下表名报错“Table doesn't exist”?先看lower_case_table_names
Linux默认lower_case_table_names = 0,意味着:
- CREATE TABLE User 和 CREATE TABLE user 是两个合法且独立的表
- SELECT * FROM user 会去找名为
user的物理文件,如果实际建的是User,就直接报错Table 'db.User' doesn't exist - 这个参数在 MySQL 启动时读取,运行中不可改,改完必须重启 mysqld
- 配置项必须写在
[mysqld]段内,写错段(比如[client])会导致启动失败,报错unknown variable
常见误操作:
- 在 Windows 开发环境用 ORM 自动生成
UserProfile表,迁移到 Linux 生产库后查询userprofile失败 - mysqldump 导出含大写表名的 SQL,在
lower_case_table_names = 1的库中导入后,表名被转成小写,但代码仍写原大小写
WHERE username = 'Admin' 却命中 'admin'?这不是表名问题,是COLLATION在起作用
字段内容比较是否区分大小写,只由该字段的排序规则(COLLATION)控制。默认的utf8mb4_general_ci或utf8mb4_unicode_ci中的_ci即表示 case-insensitive。
- 想让某字段严格区分大小写:建表时指定
COLLATE utf8mb4_bin,例如username VARCHAR(64) COLLATE utf8mb4_bin - 已有字段可修改:
ALTER TABLE users MODIFY username VARCHAR(64) COLLATE utf8mb4_bin - 临时强制区分:在查询中加
BINARY,如WHERE BINARY username = 'Admin',但注意这会让索引失效 -
BINARY不是数据类型,而是比较修饰符;utf8mb4_bin才是真正的二进制校对规则,推荐用于生产
lower_case_table_names = 2为什么最危险?
macOS 默认设为 2,表面看“建表保留大小写、查询忽略”,实则埋雷:
- CREATE TABLE A 和 CREATE TABLE a 在 APFS 文件系统上都能成功,但第二个会静默覆盖第一个的
.ibd文件(InnoDB 强制用小写存文件名) - 混合使用 MyISAM 和 InnoDB 时,元数据与物理文件大小写不一致,备份工具(如 XtraBackup)可能崩溃或跳过
- 一旦设为 2,后续几乎无法安全切换到 1 —— 没有可靠方式批量修正已存在的大小写混杂表名
- 开发用 macOS、上线跑 Linux,这种组合最容易因
lower_case_table_names差异导致迁移失败
真正容易被忽略的是:改lower_case_table_names前,你得先确认磁盘上所有表文件名是否已统一为小写;而改字段COLLATION时,别忘了测试排序结果——utf8mb4_bin下Z排在a前面,不是自然语言顺序。











