在mysql中,操作系统对大小写的敏感性决定了数据库和表的大小写敏感。所以,默认情况下,mysql在windows下是不区分大小写的,而在linux环境下数据库名与表名是严格区分大小写的。但是,mysql中存在参数lower_case_table_names,可以控制数据库名、表名的大小写是否敏感。
需要注意的是,系统库information_schema及其之下的表名是不区分大小写的。
参数说明:
- 当lower_case_table_names为0时表示区分大小写,为1时表示不区分大小写。
- 在unix,linux下lower_case_table_names默认值为0,windows下默认值是1。mac os 下默认值是2。
lower_case_table_names=0 -- 表名存储为给定的大小和比较是区分大小写的
lower_case_table_names=1 -- 表名存储在磁盘是小写的,但是比较的时候是不区分大小写
lower_case_table_names=2 -- 表名存储为给定的大小写但是比较的时候是小写的
1. 创建测试表
mysql> create database sxcdb;
query ok, 1 row affected (0.00 sec)
mysql> use sxcdb;
database changed
mysql> create table t1 (id int);
query ok, 0 rows affected (0.01 sec)
mysql> create table t2 (id int);
query ok, 0 rows affected (0.01 sec)
mysql> create table t1 (id int,name char(10));
query ok, 0 rows affected (0.00 sec)
mysql> create table t3 (id int);
query ok, 0 rows affected (0.01 sec)
mysql> insert into t1 values (1);
query ok, 1 row affected (0.00 sec)
mysql> insert into t2 values (2);
query ok, 1 row affected (0.00 sec)
mysql> insert into t1 values (1,'t1');
query ok, 1 row affected (0.00 sec)
mysql> insert into t3 values (3);
query ok, 1 row affected (0.00 sec)
我们新建t1、t2、t1、t3 四个测试表,表名既包含小写,也包含大写,并且 t1、t1 是两张不一样的表。
2. 5.7 默认情况下查询
2.1 information_schema系统库
mysql> show variables like 'lower_case_table_names';
------------------------ -------
| variable_name | value |
------------------------ -------
| lower_case_table_names | 0 |
------------------------ -------
1 row in set (0.00 sec)
mysql> use information_schema;
reading table information for completion of table and column names
you can turn off this feature to get a quicker startup with -a
database changed
mysql> select count(*) from character_sets;
----------
| count(*) |
----------
| 41 |
----------
1 row in set (0.00 sec)
mysql> select count(*) from character_sets;
----------
| count(*) |
----------
| 41 |
----------
1 row in set (0.00 sec)
默认情况下,也就是区分大小写的情况下,系统库information_schema及其之下的表名也是不区分大小写的。但是 performance_schema 和 mysql 系统库还是区分大小写的。
mysql> use performance_schema;
error 1049 (42000): unknown database 'performance_schema'
mysql> use mysql
error 1049 (42000): unknown database 'mysql'
2.2 非 information_schema系统库
mysql> show variables like 'lower_case_table_names';
------------------------ -------
| variable_name | value |
------------------------ -------
| lower_case_table_names | 0 |
------------------------ -------
1 row in set (0.00 sec)
mysql> use sxcdb;
reading table information for completion of table and column names
you can turn off this feature to get a quicker startup with -a
database changed
mysql> select * from t1;
------
| id |
------
| 1 |
------
1 row in set (0.00 sec)
mysql> select * from t2;
------
| id |
------
| 2 |
------
1 row in set (0.00 sec)
mysql> select * from t1;
------ ------
| id | name |
------ ------
| 1 | t1 |
------ ------
1 row in set (0.00 sec)
mysql> select * from t3;
------
| id |
------
| 3 |
------
1 row in set (0.00 sec)
mysql> select * from t2;
error 1146 (42s02): table 'sxcdb.t2' doesn't exist
mysql> select * from t3;
error 1146 (42s02): table 'sxcdb.t3' doesn't exist
默认情况下,mysql区分大小写,t1、t2、t1、t3 都可以访问,t2、t3 表不存在,很明显是表名区分大小写的。
3. 设置大小写区分情况下查询
3.1 修改参数
-- 不支持在线修改
mysql> set global lower_case_table_names=1;
error 1238 (hy000): variable 'lower_case_table_names' is a read only variable
-- 在my.cnf文件中添加参数
[root@mysql57 ~]# cat /etc/my.cnf|grep lower_case_table_names
lower_case_table_names=1
--重启mysql服务生效
[root@mysql57 ~]# systemctl restart mysqld
[root@mysql57 ~]#
[root@mysql57 ~]# mysql
mysql: [warning] using a password on the command line interface can be insecure.
welcome to the mysql monitor. commands end with ; or \g.
your mysql connection id is 2
server version: 5.7.27-log mysql community server (gpl)
米乐app官网下载 copyright (c) 2000, 2019, oracle and/or its affiliates. all rights reserved.
oracle is a registered trademark of oracle corporation and/or its
affiliates. other names may be trademarks of their respective
owners.
type 'help;' or '\h' for help. type '\c' to clear the current input statement.
mysql> show variables like 'lower_case_table_names';
------------------------ -------
| variable_name | value |
------------------------ -------
| lower_case_table_names | 1 |
------------------------ -------
1 row in set (0.00 sec)
3.2 再次验证查询
mysql> select * from t1;
------
| id |
------
| 1 |
------
1 row in set (0.00 sec)
mysql> select * from t1;
------
| id |
------
| 1 |
------
1 row in set (0.00 sec)
mysql> select * from t2;
------
| id |
------
| 2 |
------
1 row in set (0.00 sec)
mysql> select * from t2;
------
| id |
------
| 2 |
------
1 row in set (0.00 sec)
mysql> select * from t3;
error 1146 (42s02): table 'sxcdb.t3' doesn't exist
mysql> select * from t3;
error 1146 (42s02): table 'sxcdb.t3' doesn't exist
mysql> show tables;
-----------------
| tables_in_sxcdb |
-----------------
| t1 |
| t3 |
| t1 |
| t2 |
-----------------
4 rows in set (0.00 sec)
结论:
1)t1、t2、t1 、t2 都可以访问,但是t1 访问的其实是t1 表中数据,原来大写的t1 表中数据无法访问,访问的都是小写的t1 表。
2)t3 、t3 不管大写小写,都不能访问,这是因为改完参数后,默认都已小写的形式查询,但是小写的t3 表确实不存在,导致了原来大写的t3表也无法访问。
3.3 解决办法
- 我们尝试rename 大写的t1表,改成小写:
mysql> rename table t1 to t4;
query ok, 0 rows affected (0.00 sec)
mysql> show tables;
-----------------
| tables_in_sxcdb |
-----------------
| t1 |
| t3 |
| t2 |
| t4 |
-----------------
4 rows in set (0.00 sec)
结论:可以看到rename 操作,一样是操作的t1表,而不是大写的t1表,我们需要先将参数lower_case_table_names先还原回去,再rename t1 表。
-- 先还原回去
mysql> rename table t4 to t1;
query ok, 0 rows affected (0.00 sec)
-- 还原参数
[root@mysql57 ~]# cat /etc/my.cnf|grep lower_case_table_names
#lower_case_table_names=1
[root@mysql57 ~]# systemctl restart mysqld
mysql> use sxcdb;
reading table information for completion of table and column names
you can turn off this feature to get a quicker startup with -a
database changed
mysql>
mysql> show tables;
-----------------
| tables_in_sxcdb |
-----------------
| t1 |
| t3 |
| t1 |
| t2 |
-----------------
4 rows in set (0.00 sec)
mysql> rename table t1 to t4;
query ok, 0 rows affected (0.00 sec)
mysql> rename table t3 to t3;
query ok, 0 rows affected (0.01 sec)
mysql> show tables;
-----------------
| tables_in_sxcdb |
-----------------
| t1 |
| t2 |
| t3 |
| t4 |
-----------------
4 rows in set (0.00 sec)
3.4 再次查询
- 重新修改参数,设置不区分大小写
[root@mysql57 ~]# cat /etc/my.cnf|grep lower_case_table_names
lower_case_table_names=1
[root@mysql57 ~]# systemctl restart mysqld
mysql> use sxcdb;
reading table information for completion of table and column names
you can turn off this feature to get a quicker startup with -a
database changed
mysql> select * from t1;
------
| id |
------
| 1 |
------
1 row in set (0.00 sec)
mysql> select * from t2;
------
| id |
------
| 2 |
------
1 row in set (0.00 sec)
mysql> select * from t3;
------
| id |
------
| 3 |
------
1 row in set (0.00 sec)
mysql> select * from t4;
------ ------
| id | name |
------ ------
| 1 | t1 |
------ ------
1 row in set (0.00 sec)
mysql> select * from t3;
------
| id |
------
| 3 |
------
1 row in set (0.00 sec)
mysql> select * from t4;
------ ------
| id | name |
------ ------
| 1 | t1 |
------ ------
1 row in set (0.00 sec)
结论:t1、t2、t3、t4、t3、t4 都可以访问,不再区分表名大小写。
3.5 建表
-- 在不区分大小写情况下:
mysql> create table t5 (id int);
query ok, 0 rows affected (0.01 sec)
mysql> create table t5 (id int);
error 1050 (42s01): table 't5' already exists
mysql> show tables;
-----------------
| tables_in_sxcdb |
-----------------
| t1 |
| t2 |
| t3 |
| t4 |
| t5 |
-----------------
5 rows in set (0.00 sec)
结论:我们可以看到,建表的时候,指定了大写,实际存储的也是小写。
4. 8.0 版本不支持修改
4.1 修改参数
-- 当前参数是默认值 0
mysql> show variables like 'lower_case_table_names';
------------------------ -------
| variable_name | value |
------------------------ -------
| lower_case_table_names | 0 |
------------------------ -------
1 row in set (0.00 sec)
-- 修改参数
[root@mysql8 ~]# cat /etc/my.cnf|grep lower_case_table_names
lower_case_table_names=1
-- 启动报错
[root@mysql8 ~]# systemctl restart mysqld
job for mysqld.service failed because the control process exited with error code. see "systemctl status mysqld.service" and "journalctl -xe" for details.
-- 查看错误日志信息:提示lower_case_table_names参数值不一样,数据字典初始化失败。
2023-08-14t13:40:00.846774 08:00 0 [system] [my-010116] [server] /usr/local/mysql/bin/mysqld (mysqld 8.0.19) starting as process 1424
2023-08-14t13:40:01.568343 08:00 1 [error] [my-011087] [server] different lower_case_table_names settings for server ('1') and data dictionary ('0').
2023-08-14t13:40:01.568679 08:00 0 [error] [my-010020] [server] data dictionary initialization failed.
2023-08-14t13:40:01.568870 08:00 0 [error] [my-010119] [server] aborting
2023-08-14t13:40:02.102280 08:00 0 [system] [my-010910] [server] /usr/local/mysql/bin/mysqld: shutdown complete (mysqld 8.0.19) mysql community server - gpl.
- 查看官方文档 ,可以看到下面描述:8.0 版本lower_case_table_names变量只能在mysql服务器初始化时配置,初始化后不允许修改。
lower_case_table_names variable can only be configured when the mysql server is initialized.changing the setting after the server is initialized is prohibited.
参考连接:
4.2 m6米乐安卓版下载的解决方案
--1)如果不需要数据迁移
删除 data 目录下的所有文件,重新初始化并且指定 lower_case_table_names 值。
--2)如果需要数据迁移,大致步骤如下:
a. 先转化数据库名、表名、字段名为想要的大小写,然后mysqldump导出数据
b. 设置lower_case_table_names值,并重新初始化数据库。
c. 创建新实例,导入之前mysqldump导出的数据。
-
lower_case_table_names 不能在线修改。
-
系统库information_schema及其之下的表名是不区分大小写的。
-
在5.7版本中,原来的表中既有大写,也有小写的表名情况下,修改参数不区分大小后:
1)原来大写的表无法访问,如果存在同名的小写表,则实际操作、访问的都是小写的表;
2)新建的表,即使指定表名是大写的,实际存在的也是小写的表名。
-
8.0 版本lower_case_table_names变量只能在mysql服务器初始化时配置,初始化后不允许修改。
所以,是否需要启用大小写不区分参数,要提前规划好,尤其是在8.0版本中,初始化之后,不再允许修改,需要更加小心,防止需要数据迁移,导致其他问题。