MySQLのテーブル名大文字小文字区別:バージョン5.7と8.0の設定と挙動差異

OSのファイルシステムとテーブル名の依存関係

開発環境と本番環境でSQLの実行結果が異なる場合、その原因の多くはMySQLのテーブル名の大文字・小文字区別(Case Sensitivity)にあります。MySQLはテーブルのメタデータやデータをOSのファイルシステム上に物理的に保存します。Linux(ext4など)はファイル名の大文字・小文字を厳密に区別しますが、Windowsは区別しません。

例えば、Linux環境で CREATE TABLE UserData (...) を実行した場合、内部的には UserData という名前のファイルが作成されます。そのため、SELECT * FROM userdata を実行してもファイルが見つからずエラーになります。一方でWindowsでは同一ファイルとして認識されます。このクロスプラットフォームの差異を吸収し、統一的な挙動を提供するために lower_case_table_names パラメータが用意されています。

制御パラメータ:lower_case_table_names

このパラメータはMySQLの起動時に読み込まれ、テーブル名の保存および検索時の挙動を決定します。

  • 0: 大文字・小文字を区別します。作成時のままのケースで保存され、検索時も厳密なマッチングが要求されます(Linuxのデフォルト)。
  • 1: 大文字・小文字を区別しません。保存時および検索時にすべて小文字に正規化されます(Windowsのデフォルト)。
  • 2: 保存時は作成時のケースを維持しますが、検索時のみ小文字に変換してマッチングを行います(Linux以外のOSで有効)。

※ このパラメータはMySQLの起動前に設定する必要があり、変更後は必ずサービスの再起動が求められます。また、既存のデータベースと新しいルール間に不整合が生じると、テーブルがアクセス不能になるリスクがあります。

バージョン5.7と8.0の決定的な挙動差異

両バージョンとも同じパラメータを使用しますが、設定の柔軟性において大きな違いがあります。

バージョン Linuxデフォルト Windowsデフォルト 設定の制限事項
5.7 0(区別する) 1(区別しない) 起動後でも設定ファイルを変更し、再起動すれば反映可能
8.0 0(区別する) 1(区別しない) 初期化(初回起動)後は変更不可。初期化前に必ず設定する必要がある

MySQL 8.0 では、データディレクトリの初期化段階でこのパラメータの値が内部メタデータに固定されます。そのため、初期化後に設定ファイルを書き換えても無視されます。

環境・バージョン別の設定手順

MySQL 5.7 の設定

一時的な変更(再起動で無効化)

MySQLクライアントに接続し、システム変数を直接更新します。

SET @@GLOBAL.lower_case_table_names = 1;

※ 反映にはセッションの再接続が必要です。サーバー再起動後はデフォルト値に戻ります。

永続的な変更

  1. 設定ファイル(Linux: /etc/my.cnf、Windows: my.ini)を開きます。
  2. [mysqld] セクションに以下を追記します。
    lower_case_table_names = 1
  3. MySQLサービスを再起動します(Linux: systemctl restart mysqld)。
  4. 設定確認: SHOW VARIABLES LIKE 'lower_case_table_names';

MySQL 8.0 の設定

シナリオA:新規インストール(未初期化)

  1. 設定ファイルの [mysqld]lower_case_table_names = 1 を追記します。
  2. 初期化コマンドを実行します。
    mysqld --defaults-file=/etc/mysql/my.cnf --initialize
  3. サービスを起動すれば、パラメータが有効になった状態で稼働します。

シナリオB:既存環境の変更(再初期化が必要)

8.0の既存環境で値を変更する場合、データを退避させて初期化からやり直す必要があります。

  1. 全データベースのバックアップを取得します。
    mysqldump -u root -p --all-databases --single-transaction > complete_db_snapshot.sql
  2. MySQLサービスを停止します。
  3. データディレクトリ(datadir で指定されたパス、例: /var/lib/mysql)を完全に削除します。
  4. 設定ファイルに lower_case_table_names = 1 を追記します。
  5. データベースを再初期化し、サービスを起動します。
  6. バックアップからデータをリストアします。
    mysql -u root -p < complete_db_snapshot.sql

運用上のベストプラクティス

  • 環境の統一: Linuxサーバーでは lower_case_table_names = 1 に設定し、Windows開発環境と同一の挙動に統一することを推奨します。
  • 命名規則: パラメータの設定に関わらず、DDLやアプリケーションコード内のテーブル名はすべて小文字(またはスネークケース)で統一します。
  • 既存テーブルの修正: 既に大文字混在のテーブルがある場合、以下のようにリネームして小文字に揃えます。
    RENAME TABLE UserProfiles TO user_profiles;
  • バージョンアップ時の注意: 5.7から8.0へ移行する際、移行先の8.0初期化前に5.7と同じパラメータ値が設定されているか必ず確認してください。

補足:カラム名と照合順序(Collation)の仕組み

テーブル名の大文字・小文字区別はOSと lower_case_table_names に依存しますが、カラム名の区別ルールは異なります。カラム名の敏感性は、ストレージエンジンではなく照合順序(Collation)によって決定されます。

主要なCollationの特性は以下の通りです。

  • utf8mb4_general_ci / utf8mb4_unicode_ci: ci (case insensitive) の通り、大文字・小文字を区別しません。現代のアプリケーションでは、絵文字(4バイトUTF-8)をサポートする utf8mb4 系のCollationが標準です。
  • utf8mb4_bin: バイナリ比較を行うため、大文字・小文字を厳密に区別します(Aa は別物として扱われます)。パスワードハッシュや厳密な識別子の保存に適しています。
  • latin1_swedish_ci: 過去のMySQLバージョンでのデフォルトでしたが、マルチバイト文字のサポートが限定的なため、現在は utf8mb4 系への移行が強く推奨されます。

lower_case_table_names はテーブル名とデータベース名にのみ作用し、カラム名には一切影響を与えない点に注意が必要です。

タグ: MySQL Database Administration lower_case_table_names collation linux

9月15日 22:49 投稿