通过以上实验我们发现 lower_case_table_names 参数设为 0 时,MySQL 库表名是严格区分大小写的,而且表别名同样区分大小写但列名不区分大小写,查询时也需要严格按照大小写来书写 。同时我们注意到,允许创建名称同样但大小写不一样的库表名(比如允许 TestDb 和 testdb 库共存) 。
你有没有考虑过 lower_case_table_names 设为 0 会出现哪些可能的问题,比如说:一位同事创建了 Test 表,另一位同事在写程序调用时写成了 test 表,则会报错不存在,更甚者可能会出现 TestDb 库与 testdb 库共存,Test 表与 test 表共存的情况,这样就更加混乱了 。所以为了实现最大的可移植性和易用性,我们可以采用一致的约定,例如始终使用小写名称创建和引用库表 。也可以将 lower_case_table_names 设为 1 来解决此问题,我们来看下此参数为 1 时的情况:
# 将上述测试库删除 并将 lower_case_table_names 改为 1 然后重启数据库mysql> show variables like 'lower_case_table_names';+------------------------+-------+| Variable_name| Value |+------------------------+-------+| lower_case_table_names | 1|+------------------------+-------+# 创建数据库mysql> create database TestDb;Query OK, 1 row affected (0.02 sec)mysql> create database testdb;ERROR 1007 (HY000): Can't create database 'testdb'; database existsmysql> show databases;+--------------------+| Database|+--------------------+| information_schema || mysql|| performance_schema || sys|| testdb|+--------------------+7 rows in set (0.00 sec)mysql> use testdb;Database changedmysql> use TESTDB;Database changed# 创建表mysql> CREATE TABLE if not exists `test_tb` (->`increment_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增主键',->`stu_id` int(11) NOT NULL COMMENT '学号',->`stu_name` varchar(20) DEFAULT NULL COMMENT '学生姓名',->PRIMARY KEY (`increment_id`),->UNIQUE KEY `uk_stu_id` (`stu_id`) USING BTREE-> ) ENGINE=InnoDBDEFAULT CHARSET=utf8 COMMENT='test_tb';Query OK, 0 rows affected (0.05 sec)mysql> create table TEST_TB (id int);ERROR 1050 (42S01): Table 'test_tb' already existsmysql> show tables;+------------------+| Tables_in_testdb |+------------------+| test_tb|+------------------+# 查询表mysql> select stu_id,stu_name from test_tb limit 1;+--------+----------+| stu_id | stu_name |+--------+----------+|1001 | from1|+--------+----------+1 row in set (0.00 sec)mysql> select stu_id,stu_name from Test_Tb limit 1;+--------+----------+| stu_id | stu_name |+--------+----------+|1001 | from1|+--------+----------+1 row in set (0.00 sec)mysql> select stu_id,stu_name from test_tb as A where a.stu_id = 1002;+--------+----------+| stu_id | stu_name |+--------+----------+|1002 | dfsfd|+--------+----------+1 row in set (0.00 sec)当 lower_case_table_names 参数设为 1 时,可以看出库表名统一用小写存储,查询时不区分大小写且用大小写字母都可以查到 。这样会更易用些,程序里无论使用大写表名还是小写表名都可以查到这张表,而且不同系统间数据库迁移也更方便,这也是建议将 lower_case_table_names 参数设为 1 的原因 。
2.参数变更注意事项lower_case_table_names 参数是全局系统变量,不可以动态修改,想要变动时,必须写入配置文件然后重启数据库生效 。如果你的数据库该参数一开始为 0,现在想要改为 1,这种情况要格外注意,因为若原实例中存在大写的库表,则改为 1 重启后,这些库表将会不能访问 。如果需要将 lower_case_table_names 参数从 0 改成 1,可以按照下面步骤修改:
首先核实下实例中是否存在大写的库及表,若不存在大写的库表,则可以直接修改配置文件然后重启 。若存在大写的库表,则需要先将大写的库表转化为小写,然后才可以修改配置文件重启 。
当实例中存在大写库表时,可以采用下面两种方法将其改为小写:
1、通过 mysqldump 备份相关库,备份完成后删除对应库,之后修改配置文件重启,最后将备份文件重新导入 。此方法用时较长,一般很少用到 。
2、通过 rename 语句修改,具体可以参考下面 SQL:
# 将大写表重命名为小写表 rename table TEST to test;# 若存在大写库 则需要先创建小写库 然后将大写库里面的表转移到小写库rename table TESTDB.test_tb to testdb.test_tb;# 分享两条可能用到的SQL# 查询实例中有大写字母的表SELECTTABLE_SCHEMA,TABLE_NAMEFROMinformation_schema.`TABLES` WHERETABLE_SCHEMA NOT IN ( 'information_schema', 'sys', 'mysql', 'performance_schema' )AND table_type = 'BASE TABLE'AND TABLE_NAME REGEXP BINARY '[A-Z]'# 拼接SQL 将大写库中的表转移到小写库SELECTCONCAT( 'rename table TESTDB.', TABLE_NAME, ' to testdb.', TABLE_NAME, ';' ) FROMinformation_schema.TABLES WHERETABLE_SCHEMA = 'TESTDB';
推荐阅读
- Ubuntu 20.04更换阿里云源及安装完MySQL修改密码
- Mysql索引数据结构有多个选择,为什么一定要是B+树?
- 关于国庆节的句子有哪些?
- 前端大佬问我MySQL怎么查询最近10分钟的数据?我是这么回答他的
- 一名高级的Javaer,应该了解的 MYSQL 高级知识点
- 关于蜜桃好听的果茶名字,水果茶的制作方法
- 银行数据库迁移至MySQL,竟被时间字段这玩意耍了……
- GTID模式 mysql集群搭建
- 刘曜为什么喜欢羊献容,关于羊献容与刘曜的小说
- 最好的贡菊多少钱斤,关于金丝皇菊和贡菊的区别
