大多数のステートメントでは、MySQL がどの照合順序を使用して比較演算を行うかは明確になっています。 たとえば、次の場合、照合がカラム x
の照合であることを明確にする必要があります:
SELECT x FROM T ORDER BY x;
SELECT x FROM T WHERE x = x;
SELECT DISTINCT x FROM T;
ただし、複数のオペランドがあると、あいまいさが生じることがあります。 たとえば、次のステートメントは、カラム x
と文字列リテラル'Y'
の比較を実行します:
SELECT x FROM T WHERE x = 'Y';
x
と'Y'
の照合順序が同じ場合、比較に使用する照合順序のあいまいさはありません。 ただし、照合順序が異なる場合、比較で x
の照合順序または'Y'
の照合順序を使用する必要がありますか。 x
と 'Y'
の両方に照合順序がありますが、どちらの照合順序が優先されるでしょうか。
照合の混在は、比較以外のコンテキストでも発生する可能性があります。 たとえば、CONCAT(x,'Y')
などの複数引数の連結操作では、引数を組み合せて単一の文字列が生成されます。 結果にはどのような照合が必要ですか。
これらのような質問を解決するために、MySQL では、一方のアイテムの照合を他方のアイテムの照合に強制できるかどうかをチェックします。 MySQL は次のように強制性値を割り当てます。
明示的な
COLLATE
句の強制性は 0 です (強制可能ではありません)。照合順序の異なる 2 つの文字列を連結すると強制性は 1 になります。
カラムまたはストアドルーチンのパラメータまたはローカル変数の照合順序の強制性は 2 です。
「システム定数」 (
USER()
またはVERSION()
などの関数で返される文字列) の強制性は 3 です。リテラルの照合順序の強制性は 4 です。
数値または時間値の照合の強制性は 5 です。
NULL
またはNULL
から派生した式の強制性 6 です。
MySQL は、次のルールとともに強制性値を使用して、あいまいさを解決します。
強制性値がもっとも低い照合順序を使用します。
-
両方の側で強制性が同じ場合は、次のようになります。
両方の側が Unicode であるか、両方の側が Unicode ではない場合は、エラーになります。
-
どちらかの側に Unicode 文字セットがあり、もう一方の側に Unicode 以外の文字セットがある場合、Unicode 文字セットの側が優先され、Unicode 以外の側に自動文字セット変換が適用されます。 たとえば、次のステートメントはエラーを返しません。
SELECT CONCAT(utf8mb4_column, latin1_column) FROM t1;
utf8mb4
の文字セットとutf8mb4_column
と同じ照合順序を持つ結果を返します。latin1_column
の値は、連結する前に自動的にutf8mb4
に変換されます。 同じ文字セットのオペランドだが、
_bin
照合順序と_ci
または_cs
照合順序が混在したオペランドを使用した演算の場合、_bin
照合順序が使用されます。 これは、非バイナリ文字列とバイナリ文字列を混在させる操作によってオペランドがバイナリ文字列として評価され、データ型ではなく照合順序に適用される方法と似ています。
自動変換は SQL 標準には含まれていませんが、標準では、すべての文字セットが Unicode の「「サブセット」」であることが示されています。 「スーパーセットに適用されるものはサブセットにも適用される」というよく知られた原則があるので、Unicode の照合順序は Unicode 以外の文字列との比較にも適用できると考えられます。 より一般的に、MySQL では文字セットレパートリーの概念が使用されます。この概念は、文字セット間のサブセット関係を判断し、それ以外の場合はエラーが発生する操作でオペランドの変換を可能にするために使用されることがあります。 セクション10.2.1「文字セットレパートリー」を参照してください。
次のテーブルに、前述のルールの適用例を示します。
比較 | 使用される照合順序 |
---|---|
column1 = 'A' |
column1 の照合順序を使用します |
column1 = 'A' COLLATE x |
'A' COLLATE x の照合順序を使用します |
column1 COLLATE x = 'A' COLLATE y |
エラー |
文字列式の強制性を判断するには、COERCIBILITY()
関数を使用します (セクション12.16「情報関数」 を参照):
mysql> SELECT COERCIBILITY(_utf8'A' COLLATE utf8_bin);
-> 0
mysql> SELECT COERCIBILITY(VERSION());
-> 3
mysql> SELECT COERCIBILITY('A');
-> 4
mysql> SELECT COERCIBILITY(1000);
-> 5
mysql> SELECT COERCIBILITY(NULL);
-> 6
式 CONCAT(1, 'abc')
での引数 1
に対して行われる変換など、数値または時間値の文字列への暗黙の変換の場合、その結果は、character_set_connection
および collation_connection
システム変数で指定された文字セットおよび照合順序を持つ文字 (非バイナリ) 列になります。 セクション12.3「式評価での型変換」を参照してください。