INFORMATION_SCHEMA
テーブルの文字列カラムには utf8_general_ci
の照合順序があり、大/小文字は区別されません。 ただし、データベースやテーブルなどのファイルシステムでテーブルされるオブジェクトに対応する値の場合、基礎となるファイルシステムの特性および lower_case_table_names
システム変数の設定に応じて、INFORMATION_SCHEMA
文字列カラムでの検索では大/小文字が区別される場合と区別されない場合があります。 たとえば、ファイルシステムで大文字と小文字が区別される場合、検索では大文字と小文字が区別されることがあります。 このセクションでは、この動作と、必要に応じてその動作を変更する方法について説明します。
クエリーで、test
データベースに対し SCHEMATA.SCHEMA_NAME
カラムを検索するとします。 Linux では、ファイルシステムは大/小文字が区別されるため、SCHEMATA.SCHEMA_NAME
と'test'
の比較は一致しますが、'TEST'
との比較は一致しません:
mysql> SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA
WHERE SCHEMA_NAME = 'test';
+-------------+
| SCHEMA_NAME |
+-------------+
| test |
+-------------+
mysql> SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA
WHERE SCHEMA_NAME = 'TEST';
Empty set (0.00 sec)
これらの結果は、lower_case_table_names
システム変数が 0 に設定されている場合に発生します。 lower_case_table_names
設定が 1 または 2 の場合、2 番目のクエリーは最初のクエリーと同じ (空でない) 結果を返します。
サーバーの初期化時に使用された設定とは異なる lower_case_table_names
設定でサーバーを起動することは禁止されています。
Windows または macOS では、ファイルシステムは大/小文字を区別しないため、比較は'test'
と'TEST'
の両方に一致します:
mysql> SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA
WHERE SCHEMA_NAME = 'test';
+-------------+
| SCHEMA_NAME |
+-------------+
| test |
+-------------+
mysql> SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA
WHERE SCHEMA_NAME = 'TEST';
+-------------+
| SCHEMA_NAME |
+-------------+
| TEST |
+-------------+
このコンテキストでは、lower_case_table_names
の値に違いはありません。
前述の動作は、ファイルシステムで表されるオブジェクトに対応する値を検索する際に、INFORMATION_SCHEMA
クエリーに utf8_general_ci
照合が使用されないために発生します。
INFORMATION_SCHEMA
カラムに対する文字列操作の結果が予想と異なる場合、回避策は、明示的な COLLATE
句を使用して適切な照合を強制することです (セクション10.8.1「SQL ステートメントでの COLLATE の使用」 を参照)。 たとえば、大文字と小文字を区別しない検索を実行するには、INFORMATION_SCHEMA
カラム名とともに COLLATE
を使用します。
mysql> SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA
WHERE SCHEMA_NAME COLLATE utf8_general_ci = 'test';
+-------------+
| SCHEMA_NAME |
+-------------+
| test |
+-------------+
mysql> SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA
WHERE SCHEMA_NAME COLLATE utf8_general_ci = 'TEST';
+-------------+
| SCHEMA_NAME |
+-------------+
| test |
+-------------+
UPPER()
または LOWER()
関数を使用することもできます。
WHERE UPPER(SCHEMA_NAME) = 'TEST'
WHERE LOWER(SCHEMA_NAME) = 'test'
大文字と小文字を区別するファイルシステムのプラットフォームでも、大文字と小文字を区別しない比較を実行できますが、前述のように、必ずしも常に正しい処理になるとはかぎりません。 このようなプラットフォームでは、大文字と小文字だけが異なる名前の複数のオブジェクトが存在する可能性があります。 たとえば、city
、CITY
、および City
という名前のテーブルがすべて同時に存在することが可能です。 検索がこのようなすべての名前と一致するか、1 つのみ一致するかを検討し、それに応じてクエリーを書き込みます。 次の比較 (utf8_bin
を使用) のうち、最初の比較では大/小文字が区別されますが、それ以外の比較では区別されません:
WHERE TABLE_NAME COLLATE utf8_bin = 'City'
WHERE TABLE_NAME COLLATE utf8_general_ci = 'city'
WHERE UPPER(TABLE_NAME) = 'CITY'
WHERE LOWER(TABLE_NAME) = 'city'
INFORMATION_SCHEMA
はファイルシステムで表されていない 「virtual」 データベースであるため、INFORMATION_SCHEMA
文字列カラム内で INFORMATION_SCHEMA
自体を参照する値を検索すると、utf8_general_ci
照合が使用されます。 たとえば、SCHEMATA.SCHEMA_NAME
との比較は、プラットフォームに関係なく、'information_schema'
または 'INFORMATION_SCHEMA'
に一致します。
mysql> SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA
WHERE SCHEMA_NAME = 'information_schema';
+--------------------+
| SCHEMA_NAME |
+--------------------+
| information_schema |
+--------------------+
mysql> SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA
WHERE SCHEMA_NAME = 'INFORMATION_SCHEMA';
+--------------------+
| SCHEMA_NAME |
+--------------------+
| information_schema |
+--------------------+