BINARY
および VARBINARY
型は、非バイナリ文字列ではなくバイナリ文字列を格納する点を除き、CHAR
および VARCHAR
と似ています。 つまり、文字列ではなくバイト文字列が格納されます。 これは、binary
文字セットと照合順序があり、比較とソートは値のバイトの数値に基づいていることを意味します。
BINARY
および VARBINARY
の最大許容長は、CHAR
および VARCHAR
の場合と同じですが、BINARY
および VARBINARY
の長さは文字ではなくバイト単位で測定されます。
BINARY
および VARBINARY
データ型は CHAR BINARY
および VARCHAR BINARY
データ型とは異なります。 後者の型は、BINARY
属性によってカラムがバイナリ文字列カラムとして扱われることはありません。 代わりに、カラム文字セット (またはカラム文字セットが指定されていない場合はテーブルのデフォルト文字セット) のバイナリ (_bin
) 照合順序が使用され、カラム自体にバイナリバイト文字列ではなく非バイナリ文字列が格納されます。 たとえば、デフォルトの文字セットが utf8mb4
の場合、CHAR(5) BINARY
は CHAR(5) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin
として扱われます。 これは、binary
文字セットおよび照合順序を持つ 5 バイトのバイナリ文字列を格納する BINARY(5)
とは異なります。 binary
文字セットの binary
照合順序と非バイナリ文字セットの_bin
照合順序の違いについては、セクション10.8.5「バイナリ照合順序と_bin 照合順序」 を参照してください。
厳密な SQL モードが有効でない場合に、BINARY
または VARBINARY
カラムにその最大長を超える値を割り当てると、その値はカラムの最大長に合わせて切り捨てられ、警告メッセージが表示されます。 切捨ての場合、(警告ではなく) エラーが発生し、値の挿入を抑制するには、厳密な SQL モードを使用します。 セクション5.1.11「サーバー SQL モード」を参照してください。
BINARY
値は格納されると、特定の長さまで右側がパッド値で埋められます。 パッド値は 0x00
(ゼロバイト) です。 値は挿入のために 0x00
で右パディングされ、取得のために後続のバイトは削除されません。 ORDER BY
および DISTINCT
操作を含むすべてのバイトが比較で重要です。0x00
と領域の比較は異なり、0x00
は領域の前にソートされます。
例: BINARY(3)
カラムの場合、'a '
は挿入時に 'a \0'
になります。'a\0'
は挿入時に 'a\0\0'
になります。 挿入された両方の値は変更されずに取得されます。
VARBINARY
の場合、挿入用のパディングはなく、取得用のバイトは削除されません。 ORDER BY
および DISTINCT
操作を含むすべてのバイトが比較で重要です。0x00
と領域の比較は異なり、0x00
は領域の前にソートされます。
後続パッドバイトが削除または比較される場合、それらは無視され、カラムに一意の値を必要とするインデックスがあると、後続パッドバイト数のみが異なるカラムに値を挿入すると重複キーエラーが発生します。 たとえば、テーブルに 'a'
が含まれている場合、'a\0'
を格納しようとすると、重複キーエラーが発生します。
バイナリデータの格納に BINARY
データ型を使用する予定であり、取り出した値を格納した値とまったく同じにする必要がある場合は、先行のパディングと削除文字を考慮する必要があります。 次の例は、BINARY
値の 0x00
パディングによって、カラム値の比較がどのような影響を受けるかについて示しています。
mysql> CREATE TABLE t (c BINARY(3));
Query OK, 0 rows affected (0.01 sec)
mysql> INSERT INTO t SET c = 'a';
Query OK, 1 row affected (0.01 sec)
mysql> SELECT HEX(c), c = 'a', c = 'a\0\0' from t;
+--------+---------+-------------+
| HEX(c) | c = 'a' | c = 'a\0\0' |
+--------+---------+-------------+
| 610000 | 0 | 1 |
+--------+---------+-------------+
1 row in set (0.09 sec)
取り出される値を、パディングなしのストレージに指定した値と同じにする必要がある場合は、代わりに VARBINARY
か、いずれかの BLOB
データ型を使用することをお勧めします。