
默认情况下,MySQL 的大小写敏感性取决于操作系统:
-
Linux 系统:默认是区分大小写的。这意味着
my_table 和 My_Table 是两个完全不同的表。
-
Windows /macOS 系统:默认是不区分大小写的。这意味着
my_table 和 My_Table 被视为同一个表。
这个差异常常是导致项目在不同系统间迁移时出错的根源。
要让 MySQL 忽略大小写,你需要修改其配置文件,并重启服务。核心是设置 lower_case_table_names 这个系统变量。
这个变量有三个可能的值:
-
0:区分大小写。表名和数据库名按原样存储在磁盘上。比较时也区分大小写。这是 Linux 系统的默认值。
-
1:不区分大小写。表名和数据库名在存储时会被转换为小写,比较时也不区分大小写。这是 Windows 和 macOS 的默认值。这是实现 “忽略大小写” 最常用的设置。
-
2:表名和数据库名按原样存储在磁盘上,但在比较时会转换为小写。此选项在 MySQL 8.0 中已被废弃,并在某些平台上不再支持。
在进行任何配置更改之前,强烈建议备份你的所有数据库,以防万一。
mysqldump -u root -p --all-databases > all_databases_backup.sql
修改配置文件前,必须先停止 MySQL 服务。
sudo systemctl stop mysql
你需要找到并编辑 MySQL 的主配置文件 my.cnf。在 Debian/Ubuntu 系统中,它通常位于 /etc/mysql/my.cnf 或 /etc/mysql/mysql.conf.d/mysqld.cnf。
使用文本编辑器打开它:
sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
在 [mysqld] 配置段下,添加或修改 lower_case_table_names 的值为 1。
[mysqld]
user = mysql
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
port = 3306
basedir = /usr
datadir = /var/lib/mysql
tmpdir = /tmp
lc-messages-dir = /usr/share/mysql
skip-external-locking
lower_case_table_names = 1
这是一个非常关键且容易被忽略的步骤!
如果你是在一个已经存在数据的 Linux 系统上进行此更改(即从区分大小写改为不区分大小写),你必须手动将所有数据库目录和表文件重命名为小写。因为 lower_case_table_names=1 只会影响新创建的表,它不会自动修复已存在的大写或混合大小写的表名。
错误的做法:直接修改配置并重启。MySQL 启动时会找不到那些大写名称的表,导致服务启动失败或数据丢失。
正确的做法:
-
确认 MySQL 服务已停止。
-
进入 MySQL 的数据目录(通常是
/var/lib/mysql)。
-
将所有数据库目录重命名为小写。
sudo mv MyDatabase mydatabase
-
进入每个数据库目录,将所有表文件(
.frm, .ibd 等)也重命名为小写。
cd mydatabase
sudo mv MyTable.frm mytable.frm
sudo mv MyTable.ibd mytable.ibd
这个过程如果手动操作会非常繁琐,你可以使用 rename 命令来批量处理:
sudo rename 'y/A-Z/a-z/' *
for d in */; do
[ -d "$d" ] || continue
cd "$d"
sudo rename 'y/A-Z/a-z/' *
cd ..
done
完成所有修改后,启动 MySQL 服务。
sudo systemctl start mysql
登录 MySQL 并检查变量的值,确认修改已生效。
mysql -u root -p -e "SHOW VARIABLES LIKE 'lower_case_table_names';"
如果输出结果为 Value: 1,则表示配置成功。
+------------------------+-------+
| Variable_name | Value |
+------------------------+-------+
| lower_case_table_names | 1 |
+------------------------+-------+
现在,你在查询或创建表时,SELECT * FROM MyTable; 和 SELECT * FROM mytable; 的效果将完全一样。
-
最佳实践:无论在哪个平台上开发,都强烈建议统一使用小写字母来命名数据库、表和列。这可以从根本上避免大小写带来的所有问题。
-
MySQL 8.0+ 限制:在 MySQL 8.0 及更高版本中,
lower_case_table_names 的值在初始化数据库集群后就不能再更改。如果你尝试在已初始化的数据库上修改此值,MySQL 服务将无法启动。这意味着你必须在安装 MySQL 后,首次启动前就决定好这个值。如果已经启动过,唯一的方法是:停止服务 -> 删除数据目录 (/var/lib/mysql) -> 修改配置文件 -> 重新初始化数据库 (mysqld --initialize) -> 启动服务。这将导致所有数据丢失!
-
仅影响表名和数据库名:
lower_case_table_names 设置不会影响列名和字符串内容的大小写。例如,WHERE name = 'Alice' 和 WHERE name = 'alice' 的查询结果是不同的,除非你使用了不区分大小写的字符集(如 utf8_general_ci)。