问题是我们正在开发Windows机器,一旦完成,我们就在unix机器上部署代码。代码在Windows上正常工作,但在unix中我们得到错误,如'没有这样的表存在'更改表名后,在正确的情况下它也可以在unix中正常工作。实际上,在Windows中,默认情况下没有区分大小写的表名,但是在unix中它们确实有(读取MySQL表实际上是文件,在unix中我们有区分大小写的文件名但不在windows中)。解决方法可能是再次创建所有表,并让表名称为小写。是的,我们也可以这样做,没关系。
但是,我们仍然可以对MySql(windows机器)中的表名强加区分大小写。如果是,请告诉我如何做到这一点。
答案 0 :(得分:8)
该设置称为lower_case_table_names
。如果将其设置为0
,则比较将区分大小写。
然而,
如果在具有不区分大小写的文件名(例如Windows或Mac OS X)的系统上运行MySQL,则不应将此变量设置为0。如果在不区分大小写的文件系统上使用--lower-case-table-names = 0强制此变量为0并使用不同的字母表访问MyISAM表名,则可能会导致索引损坏。
在所有系统(包括Linux)中使所有表名小写,即。将其设置为值1
,听起来更好的选择:
表名以小写形式存储在磁盘上,名称比较不区分大小写。 MySQL在存储和查找时将所有表名转换为小写。此行为也适用于数据库名称和表别名。
答案 1 :(得分:6)
在Unix上,默认值lower_case_table_names
为0.在Windows上,默认值为1.在Mac OS X上,默认值在MySQL 4.0.18之前为1,在4.0.18之后为2。 / p>
要解决此问题,您可以在my.ini文件中查找设置:lower_case_table_names,可在以下位置找到:C:\ Program Files \ MySQL \ MySQL Server 4.1,具体取决于您运行的版本。如果你没有找到设置,你可以像我一样将它添加到my.ini文件的末尾,如下所示:
lower_case_table_names=0
请记住在测试它是否有效之前重启MySQL服务。
如果您只在一个平台上使用MySQL,则通常不必将lower_case_table_names变量从其默认值更改。但是,如果要在文件系统区分大小写不同的平台之间传输表,则可能会遇到困难。例如,在Unix上,您可以有两个名为my_table和MY_TABLE的不同表,但在Windows上,这些名称被认为是相同的。为避免数据库或表名字母的数据传输问题,您有两种选择:
在所有系统上使用lower_case_table_names = 1。这样做的主要缺点是,当您使用SHOW TABLES或SHOW DATABASES时,您看不到原始字母组中的名称。
在Unix上使用lower_case_table_names = 0,在Windows上使用lower_case_table_names = 2。这样可以保留数据库和表名的字母大小写。这样做的缺点是您必须确保您的语句始终在Windows上使用正确的字母大小引用您的数据库和表名。如果将语句转移到Unix,那么lettercase很重要,如果lettercase不正确,它们就不起作用。
异常:如果您正在使用InnoDB表并且尝试避免这些数据传输问题,则应在所有平台上将lower_case_table_names设置为1以强制将名称转换为小写。
如果您计划在Unix上将lower_case_table_names系统变量设置为1,则必须先将旧数据库和表名转换为小写,然后再停止mysqld并使用新变量设置重新启动它。
请查看MySQL网站以获取有关此内容的更多信息,以及一些重要警告http://dev.mysql.com/doc/refman/4.1/en/identifier-case-sensitivity.html
答案 2 :(得分:2)
(此答案没有给您解决问题的清晰途径,但是提供了更多的见识。)
Mac OS与Windows有不同的注意事项:
9.2.2标识符区分大小写 在MySQL中,数据库与data目录中的目录相对应。数据库中的每个表都对应于数据库目录中的至少一个文件(可能还有更多文件,具体取决于存储引擎)。触发器也对应于文件。因此,基础操作系统的区分大小写在数据库,表和触发器名称的区分大小写中起作用。这意味着这些名称在Windows中不区分大小写,但在大多数Unix版本中都区分大小写。 macOS是一个值得注意的例外,它是基于Unix的,但使用的是不区分大小写的默认文件系统类型(HFS +)。但是,macOS还支持UFS卷,这与任何Unix一样都区分大小写。请参见第1.8.1节“ MySQL对标准SQL的扩展”。 lower_case_table_names系统变量还影响服务器处理标识符区分大小写的方式,如本节稍后所述。
-https://dev.mysql.com/doc/refman/8.0/en/identifier-case-sensitivity.html
来自一些错误报告:
未能将表名完全转换为小写会在以后尝试重命名表时导致错误。 (特别是分区表)
在MacOS上,表名未使用小写的lower_case_table_names=2进行比较,这会导致重新启动服务器后的不稳定。 (缺陷号28170699,缺陷号91204)
MySQL 8.0 的重要说明:
现在禁止使用lower_case_table_names设置启动服务器,该设置与初始化服务器时使用的设置不同。该限制是必要的,因为数据字典表字段使用的归类基于初始化服务器时定义的设置,并且使用不同的设置重新启动服务器会导致标识符的排序和比较方式不一致。 (错误#27309094,错误#89035)
当我最后一次遇到问题时,我决定执行繁重的任务,以简化所有表名并更改所有代码。抱歉,我没有更好的方法。
答案 3 :(得分:1)
您可以将代码放在JPA中,将所有物理,模式,序列和表名称转换为小写,并在两个系统上使用大小写,以便数据库可以从Windows导出并可以毫不费力地导入Unix。 / p>
在某处添加此类:
public class ImprovedNamingStrategy implements PhysicalNamingStrategy {
@Override
public Identifier toPhysicalCatalogName(Identifier identifier, JdbcEnvironment jdbcEnv) {
return convert(identifier);
}
@Override
public Identifier toPhysicalColumnName(Identifier identifier, JdbcEnvironment jdbcEnv) {
return convert(identifier);
}
@Override
public Identifier toPhysicalSchemaName(Identifier identifier, JdbcEnvironment jdbcEnv) {
return convert(identifier);
}
@Override
public Identifier toPhysicalSequenceName(Identifier identifier, JdbcEnvironment jdbcEnv) {
return convert(identifier);
}
@Override
public Identifier toPhysicalTableName(Identifier identifier, JdbcEnvironment jdbcEnv) {
return convert(identifier);
}
/**
* Converts table name.
*
* @param identifier
* the identifier.
* @return the identifier.
*/
private Identifier convert(Identifier identifier) {
if (identifier == null || identifier.getText().trim().isEmpty()) {
return identifier;
}
return Identifier.toIdentifier(identifier.getText().toLowerCase());
}
}
并将此属性添加到persistence.xml
<property name="hibernate.physical_naming_strategy" value="ImprovedNamingStrategy" />