如何在MySql中强制区分大小写的表和列名?

问题描述 投票:10回答:4

问题是我们正在使用Windows机器,一旦完成,我们就在unix机器上部署代码。代码在Windows上正常工作,但在unix中我们得到错误,如'没有这样的表存在'更改表名后,在正确的情况下它也可以在unix中正常工作。实际上,在Windows中,默认情况下没有区分大小写的表名,但是在unix中它们确实有(读取MySQL表实际上是文件,在unix中我们有区分大小写的文件名但不在windows中)。解决方法可能是再次创建所有表,并让表名称为小写。是的,我们也可以这样做,没关系。

但是,我们仍然可以对MySql(windows机器)中的表名强加区分大小写。如果是,那么请让我知道如何做到这一点。

mysql windows case-sensitive
4个回答
8
投票

该设置称为lower_case_table_names。如果将其设置为0,则比较将区分大小写。

然而,

如果在具有不区分大小写的文件名(例如Windows或Mac OS X)的系统上运行MySQL,则不应将此变量设置为0。如果在不区分大小写的文件系统上使用--lower-case-table-names = 0强制此变量为0并使用不同的字母表访问MyISAM表名,则可能会导致索引损坏。

在所有系统(包括Linux)中使所有表名小写,即。将其设置为1的值,听起来更好的选择:

表名以小写形式存储在磁盘上,名称比较不区分大小写。 MySQL在存储和查找时将所有表名转换为小写。此行为也适用于数据库名称和表别名。


6
投票

在Unix上,lower_case_table_names的默认值为0.在Windows上,默认值为1.在Mac OS X上,MySQL 4.0.18之前的默认值为1,默认值为4.0.18。

要解决此问题,您可以在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时,您看不到原始lettercase中的名称。

在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
投票

(本答案并没有为您提供解决问题的明确途径,但提供了更多见解。)

Mac OS与Windows有不同的注意事项:

9.2.2标识符大小写敏感性在MySQL中,数据库对应于数据目录中的目录。数据库中的每个表对应于数据库目录中的至少一个文件(并且可能更多,取决于存储引擎)。触发器也对应于文件。因此,底层操作系统的区分大小写在数据库,表和触发器名称的区分大小写中起作用。这意味着这些名称在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的设置进行比较,这在重新启动服务器后导致不稳定。 (Bug#28170699,Bug#91204)

MySQL 8.0的一个重要注意事项:

现在禁止使用与初始化服务器时使用的设置不同的lower_case_table_names设置启动服务器。限制是必要的,因为数据字典表字段使用的排序规则基于初始化服务器时定义的设置,并且使用不同的设置重新启动服务器会导致标识符的排序和比较方式不一致。 (Bug#27309094,Bug#89035)

当我上次遇到问题时,我决定做一个艰巨的任务,即降低所有表名并更改所有代码。对不起,我没有更好的方法。


1
投票

您可以将代码放在JPA中,将所有物理,模式,序列和表名称转换为小写,并在两个系统上使用大小写,以便数据库可以从Windows导出并可以毫不费力地导入Unix。

在某个地方添加这个类:

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" />
© www.soinside.com 2019 - 2024. All rights reserved.