Linux下MySQL表名区分大小写由文件系统决定:ext4等默认区分大小写,故User与user被视为不同表;Windows因NTFS不区分大小写且MySQL设lower_case_table_names=1,故统一转小写匹配;字段名则始终不区分大小写。

Linux下MySQL表名区分大小写是文件系统决定的
MySQL本身不直接管理表名的大小写逻辑,而是把数据库目录和表文件(如 .ibd、.frm)直接映射到操作系统的文件路径上。Linux 的 ext4、XFS 等主流文件系统天生区分大小写:users 和 Users 是两个完全不同的目录名。MySQL 创建 CREATE TABLE User 时,就会在磁盘上生成 User.ibd;而执行 SELECT * FROM user 时,它会去找 user.ibd——这个文件根本不存在,于是报错 Table 'db.user' doesn't exist。
Windows不区分大小写是因为NTFS默认行为
Windows 的 NTFS 文件系统虽然保留大小写信息(比如你创建一个 Product 目录,资源管理器仍显示为 Product),但路径查找时不区分大小写。MySQL 在 Windows 上默认设置 lower_case_table_names=1,所有表名强制转小写存储(Product → product.ibd),SQL 查询时也统一转小写再匹配。所以 SELECT * FROM PRODUCT、product、PrOdUcT 全都能命中同一个文件。
改配置前必须确认当前 lower_case_table_names 值
直接修改 /etc/my.cnf 加 lower_case_table_names=1 并重启 MySQL,在 Linux 上大概率失败,原因很现实:
- 如果已有大写字母表(如
OrderInfo),MySQL 启动时会尝试加载orderinfo.ibd,但该文件实际叫OrderInfo.ibd,找不到就拒绝启动 - MySQL 8.0+ 更严格:初始化实例时若用的是
lower_case_table_names=0,后续不允许改为1,否则启动报错Cannot change lower_case_table_names after initialization - 即使绕过启动检查,已存在的混合大小写表名可能在查询时被错误归一化,导致
SHOW TABLES列出小写名,但原 SQL 引用的大写名失效
字段名为什么永远不区分大小写?
这是 MySQL 内部解析层硬编码的行为,和文件系统无关。无论操作系统或 lower_case_table_names 如何设置,SELECT name, NAME, Name FROM users 永远查的是同一个列。验证方式很简单:
Linux 安全审计工具,检查 SSH 配置、开放/监听端口、防火墙规则(ufw/iptables/nftables)、失败登录尝试、sudoers 权限...
DESCRIBE users;
输出中列名始终以定义时的大小写呈现,但执行时全被当作同义词处理。真正需要区分字段值大小写时,得靠 BINARY 或 COLLATE utf8mb4_0900_as_cs,而不是改表名规则。
最常被忽略的一点:跨平台部署时,开发用 Windows 写了 SELECT * FROM UserInfo,测试环境 Linux 没配 lower_case_table_names=1,结果上线就炸——不是代码有 bug,是表名大小写在不同环节被不同机制“翻译”了两次。










