MySQL 8.0 リファレンスマニュアル


10.2.1 文字セットレパートリー

文字セットのレパートリーとは、そのセット内の文字の集合です。

文字列式にはレパートリー属性があり、その値は次の 2 つです。

  • ASCII: 式には ASCII 文字、つまり U+0000 から U+007F までの Unicode 範囲の文字のみを含めることができます。

  • UNICODE: U+0000 から U+10FFFF の Unicode 範囲内の文字を式に含めることができます。 これには、Basic Multilingual Plane (BMP) 範囲 (U+0000 から U+FFFF) の文字と BMP 範囲外の補助文字 (U+10000 から U+10FFFF) が含まれます。

ASCII 範囲は UNICODE 範囲のサブセットであるため、ASCII レパートリーを含む文字列は、情報を失うことなく、UNICODE レパートリーを含む文字列の文字セットに安全に変換できます。 また、ascii 文字セットのスーパーセットである任意の文字セットに安全に変換できます。 (すべての MySQL 文字セットは、swe7 を除いて ascii のスーパーセットであり、スウェーデン語アクセント付き文字に一部の句読点文字が再利用されます。)

レパートリーを使用すると、照合強制性のルールがあいまいさを解決するには不十分な場合に MySQL が「照合順序の組合せが不正です」エラーを返す多くの場合に、式で文字セット変換が可能になります。 (強制性の詳細は、セクション10.8.4「式での照合の強制性」 を参照してください。)

次の説明では、式とそのレパートリーの例を挙げ、レパートリーの使用によって、文字列式の評価がどのように変わるかを示します。

  • 文字列定数のレパートリーは文字列の内容に依存し、文字列文字セットのレパートリーとは異なる場合があります。 これらのステートメントを考慮してください。

    SET NAMES utf8mb4; SELECT 'abc';
    SELECT _utf8mb4'def';

    前述の各場合、文字セットは utf8mb4 ですが、文字列には実際に ASCII 範囲外の文字が含まれていないため、そのレパートリーは UNICODE ではなく ASCII です。

  • ascii 文字セットを持つカラムには、その文字セットのために ASCII レパートリーがあります。 次のテーブルでは、c1 には ASCII レパートリーがあります。

    CREATE TABLE t1 (c1 CHAR(1) CHARACTER SET ascii);

    次の例では、レパートリーがないときにエラーが発生する場合に、レパートリーによってどのように結果が求められるようになるかを示しています。

    CREATE TABLE t1 (
      c1 CHAR(1) CHARACTER SET latin1,
      c2 CHAR(1) CHARACTER SET ascii
    );
    INSERT INTO t1 VALUES ('a','b');
    SELECT CONCAT(c1,c2) FROM t1;

    レパートリーがない場合、次のエラーが発生します。

    ERROR 1267 (HY000): Illegal mix of collations (latin1_swedish_ci,IMPLICIT)
    and (ascii_general_ci,IMPLICIT) for operation 'concat'

    レパートリーを使用すると、サブセットからスーパーセットへ (ascii から latin1 へ) の変換を行うことができ、結果が返されます。

    +---------------+
    | CONCAT(c1,c2) |
    +---------------+
    | ab            |
    +---------------+
  • 1 つの文字列引数を持つ関数は、その引数のレパートリーを継承します。 引数に ASCII レパートリーがあるため、UPPER(_utf8mb4'abc') の結果には ASCII レパートリーがあります。 (_utf8mb4 イントロデューサにもかかわらず、文字列'abc'に ASCII 範囲外の文字が含まれていません。)

  • 文字列を返すが、文字列引数を持たず、結果文字セットとして character_set_connection を使用する関数の場合、結果のレパートリーは、character_set_connectionascii である場合は ASCII に、それ以外の場合は UNICODE になります。

    FORMAT(numeric_column, 4);

    レパートリーを使用するかどうかによって、MySQL が次の例をどのように評価するかが変わります。

    SET NAMES ascii;
    CREATE TABLE t1 (a INT, b VARCHAR(10) CHARACTER SET latin1);
    INSERT INTO t1 VALUES (1,'b');
    SELECT CONCAT(FORMAT(a, 4), b) FROM t1;

    レパートリーがない場合、次のエラーが発生します。

    ERROR 1267 (HY000): Illegal mix of collations (ascii_general_ci,COERCIBLE)
    and (latin1_swedish_ci,IMPLICIT) for operation 'concat'

    レパートリーを使用すると、次のように結果が返されます。

    +-------------------------+
    | CONCAT(FORMAT(a, 4), b) |
    +-------------------------+
    | 1.0000b                 |
    +-------------------------+
  • 複数の文字列引数を持つ関数は、UNICODEASCII よりも広い場合に、結果レパートリーに「ワイドスト」引数 repertoire を使用します。 次の CONCAT() 呼び出しを考えてみます。

    CONCAT(_ucs2 X'0041', _ucs2 X'0042')
    CONCAT(_ucs2 X'0041', _ucs2 X'00C2')

    最初のコールでは、両方の引数が ASCII 範囲内にあるため、レパートリーは ASCII です。 2 番目のコールでは、2 番目の引数が ASCII 範囲外であるため、レパートリーは UNICODE です。

  • 関数の戻り値のレパートリーは、結果の文字セットおよび照合順序に影響する引数のみのレパートリーに基づいて決定されます。

    IF(column1 < column2, 'smaller', 'greater')

    結果のレパートリーは、2 つの文字列引数 (2 番目の引数と 3 番目の引数) がどちらも ASCII レパートリーなので、ASCII です。 最初の引数は、式で文字列値を使用する場合でも、結果のレパートリーにとっては重要ではありません。


関連キーワード:  文字, セット, レパートリー, 照合, 順序, ASCII, 範囲, utf, ascii, リファレンス