问题描述

博主最近接手一个项目,代码大部分都是祖传代码了,最开始启动项目运行并没有什么问题,但是到部署到Linux服务器上的时候,却发现有些地方的请求直接500错误了。这就显得有点莫名其妙了,于是查看日志进行分析:

image-20231016154225050

很明显就是SQL语法错误了,没有EMS_ROLE这个表,根本查找不到,所以就报错了。

进一步结合代码分析查看日志,发现这条SQL是由通用mapper生成的。

注意到启动日志:

image-20231016154718780

也就是生成的mapper就是按照大写的表生成的了,那再看一下代码实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Entity
@Table(name="EMS_ROLE")
public class RoleVO implements VO {

@Id
@Column(name="roleId")
//@GeneratedValue(generator = "UUID")
//@GeneratedValue(strategy = GenerationType.IDENTITY)
private int roleId;// varchar2(50) primary key,
@Column(name="superRoleId")
private Integer superRoleId;

//
}

好家伙,表名映射直接就用大写了吗?难怪报错。

问题分析

问题源头知道了,就是表名映射大写造成的嘛,那么为什么本地跑的时候为什么就没事,部署在服务器上就不行呢?

直接问ChatGPT,回答如下:

在默认情况下,MySQL的表名在Windows操作系统上不区分大小写,而在类Unix操作系统(如Linux)上是区分大小写的。这是因为Windows对文件名和表名不区分大小写,而类Unix系统对它们区分大小写。

如果你希望在所有操作系统上都对表名进行大小写不敏感的查询,可以使用以下方法之一:

  1. 修改配置文件: 在MySQL配置文件(通常是my.cnfmy.ini)中添加或修改以下配置:
1
2
[mysqld]
lower_case_table_names = 1

之后,重新启动MySQL服务。

  1. 启动MySQL时指定参数: 在启动MySQL服务时,通过命令行参数指定大小写敏感性:
1
mysqld --lower_case_table_names=1

请注意,修改这个设置可能会影响现有数据库,因此在执行之前请谨慎考虑。如果已经有现有的数据库,最好在修改之前备份数据。

总的来说,MySQL提供了一些配置选项,允许你选择表名是否区分大小写,但在默认情况下,行为是与操作系统相关的。

也就是说在Windows下MySQL是不区分表名大小写的,Linux下却是区分的,并且可以通过修改my.conf配置文件来开启自动表名大小写。

那么问题又来了,为什么会有这样的区分呢?继续问chat:

这主要是因为不同操作系统对于文件名和标识符的大小写敏感性的处理方式不同。

Windows系统: Windows操作系统对于文件名和标识符(比如表名)默认是不区分大小写的。这是因为Windows早期的文件系统(如FAT、FAT32)是不区分大小写的,这一特性一直被保留下来,即使在支持区分大小写的文件系统(如NTFS)中,Windows默认也是不区分大小写的。

类Unix系统(Linux等): 在Unix-like系统上,文件系统通常是区分大小写的。这种设计考虑到了系统的灵活性和兼容性,允许用户创建大小写敏感的文件和目录。因此,数据库系统在这些系统上默认会区分表名的大小写。

MySQL为了适应不同操作系统的习惯,采取了一种默认的处理方式,但也提供了相应的配置选项,允许用户根据需要调整表名的大小写敏感性。

这样的设计历史上是为了与底层文件系统的特性相匹配,确保在不同操作系统上的一致性。不同操作系统对大小写

也就是说是系统设计的历史原因造成的嘛,那为啥我这个项目中原来的疼要把表名大写呢?

继续问:

在MySQL中,对于表名的大小写风格(大写、小写或混合大小写)通常是由个人或团队的编码规范和偏好来决定的。不同的人可能有不同的偏好,而这并没有一个明确的规定哪种方式是绝对好或不好的。

有人选择将MySQL查询语句中的表名大写,可能有以下一些考虑:

  1. 可读性: 大写表名可以使关键元素在查询语句中更容易识别,提高了可读性。对于复杂的查询语句,这有助于清晰地区分关键字和表名。

  2. 一致性: 采用统一的大小写规范有助于保持代码的一致性,提高团队协作的效率。在整个代码库中,表名的大小写保持一致有助于降低错误和提高可维护性。

  3. 避免歧义: 在某些情况下,数据库可能部署在区分大小写的文件系统上,为了避免可能的歧义,选择一种统一的命名约定是有意义的。

然而,也有人更喜欢使用小写或混合大小写,这通常取决于个人或团队的偏好。在MySQL中,表名的大小写处理取决于操作系统和配置选项。无论是大写还是小写,关键是在整个项目中保持一致性,并根据团队的实际需求和习惯选择合适的方式。

其实也就是个习惯问题吧,至于所说的这三点优点我感觉不是很认同,就像我这种情况,把项目部署在Linux中就会产生上面说的问题。最好的方法我感觉还是:表名是什么,就写什么。