CHAR
型と VARCHAR
型は似ていますが、格納および取得方法が異なります。 また、最大長と、末尾のスペースが保持されるかどうかという点でも異なります。
CHAR
型と VARCHAR
型には、格納する最大文字数を表す長さが宣言されています。 たとえば、CHAR(30)
には最大 30 文字を格納できます。
CHAR
カラムの長さは、テーブルを作成したときに宣言した長さに修正されます。 この長さには、0 から 255 までの任意の値を指定できます。 CHAR
値は格納されると、指定された長さになるように右側がスペースで埋められます。 PAD_CHAR_TO_FULL_LENGTH
SQL モードが有効になっていないかぎり、CHAR
値が取り出されるときに、末尾のスペースが削除されます。
VARCHAR
カラム内の値は可変長の文字列です。 長さは 0 から 65,535 までの値で指定できます。 VARCHAR
カラムの有効な最大長は、最大行サイズ (65,535 バイト、すべてのカラムで共有される) と使用される文字セットによって決まります。 セクション8.4.7「テーブルカラム数と行サイズの制限」を参照してください。
CHAR
とは対照的に、VARCHAR
値は、1 バイトまたは 2 バイト長のプリフィクスの付いたデータとして格納されます。 長さプリフィクスは、値に含まれるバイト数を示します。 255 バイト以下の値を格納するカラムでは 1 バイト長のプリフィクスを使用し、255 バイトよりも大きい値を格納するカラムでは 2 バイト長のプリフィクスを使用します。
厳密な SQL モードが有効でない場合に、CHAR
または VARCHAR
カラムにその最大長を超える値を割り当てると、その値はカラムの最大長に合わせて切り捨てられ、警告メッセージが表示されます。 スペース以外の文字の切り捨てに関しては、厳密な SQL モードを使用することで、警告ではなくエラーを発生させて、その値の挿入を抑制できます。 セクション5.1.11「サーバー SQL モード」を参照してください。
VARCHAR
カラムの場合、使用している SQL モードに関係なく、カラム長を超える末尾のスペースは挿入前に切り捨てられ、警告メッセージが表示されます。 CHAR
カラムの場合、SQL モードに関係なく、超過した末尾のスペースは通知なしに挿入される値から切り捨てられます。
VARCHAR
値は格納されるときに埋められません。 標準 SQL に従い、値を格納し取り出すときに末尾のスペースは保持されます。
次の表は、CHAR(4)
カラムと VARCHAR(4)
カラムにさまざまな文字列値を格納した結果を表示して、CHAR
と VARCHAR
の違いを示しています (カラムには latin1
などのシングルバイト文字セットを使用するものとします)。
値 | CHAR(4) |
必要なストレージ | VARCHAR(4) |
必要なストレージ |
---|---|---|---|---|
'' |
' ' |
4 バイト | '' |
1 バイト |
'ab' |
'ab ' |
4 バイト | 'ab' |
3 バイト |
'abcd' |
'abcd' |
4 バイト | 'abcd' |
5 バイト |
'abcdefgh' |
'abcd' |
4 バイト | 'abcd' |
5 バイト |
テーブルの最後の行に格納されている値が厳密な SQL モードを使用していない場合のみを適用します。厳密モードが有効な場合、カラムの長さを超える値は保管されていませんであり、エラーが発生します。
InnoDB
では、768 バイト以上の固定長フィールドが可変長フィールドとしてエンコードされ、オフページに格納できます。 たとえば、utf8mb4
と同様に、文字セットの最大バイト長が 3 より大きい場合、CHAR(255)
カラムは 768 バイトを超えることがあります。
所定の値が CHAR(4)
および VARCHAR(4)
カラムに格納されると、取り出しのときに末尾のスペースが CHAR
カラムから削除されるので、カラムから取り出された値は必ずしも同じではありません。 次の例はこの違いを示しています。
mysql> CREATE TABLE vc (v VARCHAR(4), c CHAR(4));
Query OK, 0 rows affected (0.01 sec)
mysql> INSERT INTO vc VALUES ('ab ', 'ab ');
Query OK, 1 row affected (0.00 sec)
mysql> SELECT CONCAT('(', v, ')'), CONCAT('(', c, ')') FROM vc;
+---------------------+---------------------+
| CONCAT('(', v, ')') | CONCAT('(', c, ')') |
+---------------------+---------------------+
| (ab ) | (ab) |
+---------------------+---------------------+
1 row in set (0.06 sec)
CHAR
、VARCHAR
および TEXT
カラムの値は、カラムに割り当てられた文字セット照合に従ってソートおよび比較されます。
MySQL 照合には、UCA 9.0.0 以上に基づく Unicode 照合以外の PAD SPACE
のパッド属性があり、これには NO PAD
のパッド属性があります。(セクション10.10.1「Unicode 文字セット」 を参照)。
照合のパッド属性を決定するには、PAD_ATTRIBUTE
カラムを含む INFORMATION_SCHEMA
COLLATIONS
テーブルを使用します。
非バイナリ文字列 (CHAR
、VARCHAR
および TEXT
値) の場合、文字列照合パッド属性によって、文字列の末尾にある末尾の空白の比較での処理が決定されます。 NO PAD
照合順序では、他の文字と同様に、比較で末尾のスペースが重要として扱われます。 PAD SPACE
照合順序では、比較で末尾のスペースは重要ではありません。文字列は末尾のスペースに関係なく比較されます。 比較での後続領域の処理を参照してください。 サーバーの SQL モードは、末尾の空白に関する比較動作には影響しません。
MySQL の文字セットおよび照合順序の詳細は、第10章「文字セット、照合順序、Unicode」を参照してください。 ストレージ要件の追加情報については、セクション11.7「データ型のストレージ要件」を参照してください。
後続パッド文字が削除または比較される場合、一意の値を必要とするインデックスがカラムにあると、後続パッド文字の数のみが異なるカラム値に挿入すると重複キーエラーが発生します。 たとえば、テーブルに 'a'
が含まれている場合、'a '
を格納しようとすると、重複キーエラーが発生します。