VillageSQL is a drop-in replacement for MySQL with extensions.
All examples on this page work on VillageSQL. Install Now →
mysql -u root -p sakila でクライアントを開いてください。
大文字と小文字の区別の仕組み
クエリの中の何もそれを決めません。決めるのは照合順序であり、すべてのテキスト列が 1 つ持っています。文字セットは列が保持できる文字を定め、その照合順序は文字を どう比較するかを定めます。1 つの比較に限って照合順序を上書きするにはCOLLATE
を使います。
COLLATION_NAME を比較に使わせたい照合順序に、SEARCH_TEXT を一致させる値に
置き換えます。
例
- 大文字と小文字だけが異なる 2 つの文字列は等しい
- 列に対しても同じことが成り立つ
小文字の検索語が大文字のタイトルを見つけます。
- 列の照合順序を読む
ci は大文字と小文字を区別しない
(case-insensitive) という意味で、例 2 が一致したのはそのためです。ai は
アクセントを区別しない (accent-insensitive) という意味で、別の働きをします。
この照合順序では 'e' = 'é' は真ですが、utf8mb4_0900_as_cs では偽です。
この表は、自分の列の照合順序名の意味でもあります。上のクエリを任意のテーブルと列に
対して実行すると、どのルールの下で作業しているかが分かります。
- 大文字と小文字を区別する比較を求める
列に対する COLLATE はインデックス検索を手放す
列のインデックスはその列自身の照合順序で作られているため、別の照合順序での 比較は、一致する値を見つけるのにそれを使えません。上のクエリに対するEXPLAIN
は、検索ではなく 1,000 行すべてのスキャンを報告します。1,000 本の映画では何の
コストもかかりませんが、大きなテーブルでは大きなコストになります。すべての
クエリで大文字と小文字を区別する一致が必要な場合は、
文字セットと照合順序のガイドで、代わりに列をそのように
保存する方法を説明しています。
デフォルトはどこから来るのか
照合順序なしで作成されたデータベースはサーバーのものを、テーブルはデータベースの ものを、列はテーブルのものを引き継ぎます。したがって、その履歴のどこにも照合 順序が指定されていない列は、サーバーの設定のせいで大文字と小文字を区別せずに 比較しています。名前の前の@@ はサーバーの設定を読み、この 2 つはどれを
引き継いだかを教えてくれます。
識別子は別のルールに従う
列名は決して大文字と小文字を区別しません。データベース名とテーブル名は別の 問題で、lower_case_table_names が決めます。
SELECT @@lower_case_table_names; を実行すると、自分の状況が分かります。
セッションからは変更できません。SET GLOBAL lower_case_table_names=1 は
ERROR 1238 (HY000): Variable 'lower_case_table_names' is a read only variable
と答えます。これは起動時の設定で、サーバーが最初にどう設定されたかに結び付いて
いるため、答えは今いるサーバーの性質として扱ってください。
実践的な助言は答えに依存しません。すべてのデータベース名とテーブル名を大文字か
小文字のどちらかに統一して書き、そのつづりをどこでも使ってください。そうすれば、同じ SQL を 2 つの
サーバー間で移動しても、動いていたクエリが、存在しないテーブルのエラーである
ERROR 1146 (42S02) になることはありません。
まとめ
- 通常の照合順序は
_ciで終わるため、文字列比較は大文字と小文字を無視すると考えてください。 - 列の照合順序は
INFORMATION_SCHEMA.COLUMNSから読みます。 - 照合順序の名前は末尾から読みます。
_ciと_aiは無視し、_cs、_as、および_binは区別します。 - 一度限りの大文字と小文字を区別する比較には
COLLATEを使い、インデックス検索を手放すことを受け入れてください。 lower_case_table_namesが何であれ、すべてのデータベース名とテーブル名のつづりを 1 つに保ちます。
関連項目
- LIKE — これが最初に現れる場所
- REGEXP — 同じルールと、別の上書き方法
- MySQL の文字セットと照合順序 — 列のための照合順序の選び方
- MySQL で utf8mb4 を使う — 通常の照合順序の背後にある文字セット