CHAR
と
VARCHAR
型は似ていますが、格納、検索される方法が異なります。また、最大長さと、末尾のスペースが保持されるかどうかという点でも異なります。
CHAR
と
VARCHAR
型には、格納したい最大文字数を表す長さが宣言されています。たとえば、CHAR(30)
は最大 30 文字まで持つことができます。
CHAR
カラムの長さは、テーブルを作成したときに宣言した長さに修正されます。この長さには、0
から 255
までの任意の値を指定できます。CHAR
型の値は、格納時に、指定された長さになるよう右側にスペースが埋め込まれます。CHAR
値の取り出し時には、PAD_CHAR_TO_FULL_LENGTH
SQL
モードが有効になっていないかぎり、末尾のスペースが削除されます。
VARCHAR
カラム内の値は可変長の文字列です。長さは 0
から 65,535
までの値で指定できます。VARCHAR
カラムの有効な最大長は、最大行サイズ (65,535
バイト、すべてのカラムで共有される)
と使用されるキャラクタセットによって決まります。
CHAR
とは対照的に、VARCHAR
値は 1 バイトまたは 2
バイトの長さ接頭辞が付いたデータとして格納されます。長さ接頭辞は、値に含まれるバイト数を示します。255
バイト以下の値を格納するカラムでは 1
バイト長の接頭辞を使用し、255
バイトよりも大きい値を格納するカラムでは 2
バイト長の接頭辞を使用します。
厳密な SQL
モードが有効でない場合に、CHAR
または VARCHAR
カラムにその最大長を超える値を割り当てると、その値はカラムの最大長に合わせて切り捨てられ、警告メッセージが表示されます。スペース以外の文字の切り捨てに関しては、厳密な
SQL
モードを使用することで、警告ではなくエラーを発生させて、その値の挿入を抑制することができます。Server SQL Modes
を参照してください。
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 バイト |
表の最終行に格納済みとして示されている値は、厳密モードを使用していないときにだけ当てはまります。MySQL が厳密モードで実行されている場合、カラム長を超える値は格納されず、エラーが発生します。
もし規定の値が 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
カラムの中の値は、そのカラムに指定されたキャラクタセットの照合に従って格納、比較されます。
MySQL のすべての照合は
PADSPACE
型のものです。これは、MySQL のすべての
CHAR
値と
VARCHAR
値が末尾のスペースを無視して比較されるということを意味します。例
:
mysql>CREATE TABLE names (myname CHAR(10), yourname VARCHAR(10));
Query OK, 0 rows affected (0.09 sec) mysql>INSERT INTO names VALUES ('Monty ', 'Monty ');
Query OK, 1 row affected (0.00 sec) mysql>SELECT myname = 'Monty ', yourname = 'Monty ' FROM names;
+--------------------+----------------------+ | myname = 'Monty ' | yourname = 'Monty ' | +--------------------+----------------------+ | 1 | 1 | +--------------------+----------------------+ 1 row in set (0.00 sec)
これは MySQL のすべてのバージョンについて言えることであり、サーバーの SQL モードの影響を受けることはありません。
MySQL
のキャラクタセットと照合の詳細は、項6.4.1. 「CHAR
と
VARCHAR
型」を参照してください。
後続文字が剥ぎ取られたり、比較がそれらを無視する場合は、もしカラムが固有の値を要求するインデックスを持っていたら、後続文字数だけが異なるカラム値への挿入は重複キーエラーになります。たとえば、テーブルに
'a'
が含まれている場合、'a '
を格納しようとすると、重複キーエラーが発生します。