10 Stimmen

Wie erzwingt man in MySql die Groß- und Kleinschreibung von Tabellen- und Spaltennamen?

Die Sache ist, dass wir auf einer Windows-Maschine arbeiten und sobald wir fertig sind, deployen wir den Code auf einer Unix-Maschine. Der Code funktioniert einwandfrei auf Windows, aber auf Unix erhalten wir den Fehler 'Tabelle existiert nicht', nachdem wir den Tabellennamen im richtigen Fall geändert haben, funktioniert es auch auf Unix. Tatsächlich gibt es auf Windows standardmäßig keine tabellensensitiven Tabellennamen, aber auf Unix schon ( es wird gesagt, dass MySQL-Tabellen tatsächlich Dateien sind und auf Unix haben wir Dateinamen, die Groß- und Kleinschreibung beachten, aber nicht auf Windows ). Ein Workaround könnte sein, alle Tabellen erneut zu erstellen und den Tabellennamen in Kleinbuchstaben zu verwenden. Ja, das können wir auch tun, das ist in Ordnung.

Aber können wir trotzdem die Groß- und Kleinschreibung von Tabellennamen in MySql erzwingen ( auf der Windows-Maschine ). Wenn ja, lassen Sie mich bitte wissen, wie das geht.

8voto

Pekka Punkte 429407

Die Einstellung heißt lower_case_table_names. Wenn Sie es auf 0 setzen, sind Vergleiche zwischen Groß- und Kleinschreibung beachtet.

Allerdings

Sie sollten diese Variable nicht auf 0 setzen, wenn Sie MySQL auf einem System ausführen, das Dateinamen ohne Groß- und Kleinschreibung hat (wie Windows oder Mac OS X). Wenn Sie diese Variable auf einem System ohne Groß- und Kleinschreibung erzwingen und auf einem Fall-sensitiven Dateisystem MyISAM-Tabellennamen mit unterschiedlichen Groß- und Kleinschreibung verwenden, kann es zu Indexkorruption kommen.

Es scheint die bessere Option zu sein, alle Tabellennamen auf allen Systemen (einschließlich Linux) in Kleinbuchstaben umzuwandeln, d.h. ihn auf einen Wert von 1 zu setzen:

Tabellennamen werden auf der Festplatte in Kleinbuchstaben gespeichert und Namensvergleiche sind nicht mehr Groß- und Kleinschreibung beachtet. MySQL wandelt alle Tabellennamen in Kleinbuchstaben um beim Speichern und Abrufen. Dieses Verhalten gilt auch für Datenbanknamen und Tabellenaliasnamen.

6voto

Pentium10 Punkte 198024

Unter Unix ist der Standardwert von lower_case_table_names 0. Unter Windows beträgt der Standardwert 1. Unter Mac OS X beträgt der Standardwert 1 vor MySQL 4.0.18 und 2 ab 4.0.18.

Um dies zu beheben, können Sie nach der Einstellung lower_case_table_names in Ihrer my.ini-Datei suchen, die sich in oder um den Ordner: C:\Program Files\MySQL\MySQL Server 4.1 befindet, abhängig von der Version, die Sie verwenden. Wenn Sie die Einstellung nicht finden, können Sie sie einfach am Ende der my.ini-Datei hinzufügen, wie ich es getan habe, so:

lower_case_table_names=0

Vergessen Sie nicht, den MySQL-Dienst neu zu starten, bevor Sie testen, ob es funktioniert.

Wenn Sie MySQL nur auf einer Plattform verwenden, müssen Sie die lower_case_table_names-Variable normalerweise nicht von ihrem Standardwert ändern. Sie können jedoch auf Schwierigkeiten stoßen, wenn Sie Tabellen zwischen Plattformen übertragen, die sich in der Groß- und Kleinschreibung des Dateisystems unterscheiden. Beispielsweise können Sie unter Unix zwei verschiedene Tabellen namens my_table und MY_TABLE haben, aber unter Windows gelten diese Namen als identisch. Um Datenübertragungsprobleme aufgrund der Groß- und Kleinschreibung von Datenbank- oder Tabellennamen zu vermeiden, haben Sie zwei Möglichkeiten:

Verwenden Sie lower_case_table_names=1 auf allen Systemen. Der Hauptnachteil dabei ist, dass Sie bei der Verwendung von SHOW TABLES oder SHOW DATABASES die Namen nicht in ihrer ursprünglichen Groß- und Kleinschreibung sehen.

Verwenden Sie lower_case_table_names=0 unter Unix und lower_case_table_names=2 unter Windows. Damit wird die Groß- und Kleinschreibung von Datenbank- und Tabellennamen erhalten. Der Nachteil dabei ist, dass Sie sicherstellen müssen, dass Ihre Anweisungen auf Windows immer auf Ihre Datenbank- und Tabellennamen mit der richtigen Groß- und Kleinschreibung verweisen. Wenn Sie Ihre Anweisungen auf Unix übertragen, wo die Groß- und Kleinschreibung wichtig ist, funktionieren sie nicht, wenn die Groß- und Kleinschreibung falsch ist.

Ausnahme: Wenn Sie InnoDB-Tabellen verwenden und diese Datenübertragungsprobleme vermeiden möchten, sollten Sie auf allen Plattformen lower_case_table_names auf 1 setzen, um die Namen in Kleinbuchstaben zu konvertieren.

Wenn Sie beabsichtigen, die Systemvariable lower_case_table_names auf Unix auf 1 zu setzen, müssen Sie zuerst Ihre alten Datenbank- und Tabellennamen in Kleinbuchstaben konvertieren, bevor Sie mysqld anhalten und mit der neuen Variableneinstellung neu starten.

Bitte besuchen Sie die MySQL-Website für weitere Informationen dazu und einige wichtige Warnhinweise http://dev.mysql.com/doc/refman/4.1/en/identifier-case-sensitivity.html

2voto

Rick James Punkte 120626

(Diese Antwort gibt Ihnen keinen klaren Lösungsweg, sondern bietet mehr Einblick.)

Mac OS hat andere Überlegungen als Windows:

9.2.2 Identifizierung der Groß-/Kleinschreibung In MySQL entsprechen Datenbanken Verzeichnissen innerhalb des Datenverzeichnisses. Jede Tabelle innerhalb einer Datenbank entspricht mindestens einer Datei innerhalb des Datenbankverzeichnisses (und möglicherweise mehr, je nach dem verwendeten Speichermechanismus). Trigger entsprechen ebenfalls Dateien. Folglich spielt die Groß-/Kleinschreibung des zugrunde liegenden Betriebssystems eine Rolle bei der Groß-/Kleinschreibung von Datenbank-, Tabellen- und Triggernamen. Das bedeutet, dass solche Namen in Windows nicht auf die Groß-/Kleinschreibung achten, aber in den meisten Unix-Varianten die Groß-/Kleinschreibung beachtet wird. Eine bemerkenswerte Ausnahme ist macOS, das auf Unix basiert, aber ein standardmäßiges Dateisystemtyp (HFS+) verwendet, das nicht auf die Groß-/Kleinschreibung achtet. macOS unterstützt jedoch auch UFS-Volumes, die genauso wie auf jedem Unix die Groß-/Kleinschreibung beachten. Siehe Abschnitt 1.8.1, “MySQL-Erweiterungen zum Standard-SQL”. Die Systemvariable lower_case_table_names beeinflusst auch, wie der Server die Groß-/Kleinschreibung von Identifikatoren behandelt, wie später in diesem Abschnitt beschrieben.

-- https://dev.mysql.com/doc/refman/8.0/en/identifier-case-sensitivity.html

Aus einigen Fehlerberichten:

Das Nicht-Umwandeln von Tabellennamen in Kleinbuchstaben führte später zu Fehlern, wenn versucht wurde, Tabellen umzubenennen. (insbesondere Partitionierungs-Tabellen)

Tabellennamen wurden auf macOS mit einer Einstellung von lower_case_table_names=2 nicht in Kleinbuchstaben verglichen, was nach einem Neustart des Servers zu Instabilität führte. (Bug #28170699, Bug #91204)

Eine wichtige Note für MySQL 8.0:

Es ist jetzt verboten, den Server mit einer lower_case_table_names-Einstellung zu starten, die sich von der Einstellung unterscheidet, die beim Initialisieren des Servers verwendet wurde. Die Beschränkung ist notwendig, da Sortierungen, die von Datenwörterbuchtabellenfeldern verwendet werden, basierend auf der beim Initialisieren des Servers definierten Einstellung sind, und ein Neustart des Servers mit einer anderen Einstellung würde Inkonsistenzen bezüglich der Reihenfolge und Vergleich der Identifikatoren einführen. (Bug #27309094, Bug #89035)

Als ich das letzte Mal auf das Problem gestoßen bin, habe ich mich entschlossen, die mühsame Aufgabe durchzuführen, alle Tabellennamen in Kleinbuchstaben umzuwandeln und den gesamten Code zu ändern. Entschuldigung, ich habe keinen besseren Weg.

1voto

K.Nicholas Punkte 9695

Sie können Code in JPA einfügen, um alle Ihre physischen, Schema-, Sequenz- und Tabellennamen in Kleinbuchstaben umzuwandeln und den Fall auf beiden Systemen zu verwenden, damit die Datenbank von Windows exportierbar und auf Unix importierbar ist, ohne Probleme zu verursachen.

Fügen Sie diese Klasse irgendwo hinzu:

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);
    }

    /**
     * Konvertiert den Tabellennamen.
     *
     * @param identifier
     *            der Bezeichner.
     * @return der Bezeichner.
     */
    private Identifier convert(Identifier identifier) {
        if (identifier == null || identifier.getText().trim().isEmpty()) {
            return identifier;
        }
        return Identifier.toIdentifier(identifier.getText().toLowerCase());
    }
}

und fügen Sie diese Eigenschaft zu Ihrer persistence.xml hinzu

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X