10.1.7.7 BINARY 演算子

BINARY 演算子は、それに続く文字列をバイナリ文字列にキャストします。これは、比較を文字ごとでなくバイトごとに強制的に実行させる簡単な方法です。また、BINARY では末尾の空白文字が重要になります。

mysql> SELECT 'a' = 'A';
        -> 1
mysql> SELECT BINARY 'a' = 'A';
        -> 0
mysql> SELECT 'a' = 'a ';
        -> 1
mysql> SELECT BINARY 'a' = 'a ';
        -> 0

BINARY strCAST(str AS BINARY) の略でもあります。

文字カラム定義内の BINARY 属性には別の効果があります。BINARY 属性で定義された文字カラムには、カラム文字セットのバイナリ照合順序が割り当てられます。すべての文字セットにバイナリ照合順序があります。たとえば、latin1 文字セットのバイナリ照合順序は latin1_bin です。このためテーブルのデフォルト文字セットが latin1 の場合、次の 2 つのカラム定義は同等になります。

CHAR(10) BINARY
CHAR(10) CHARACTER SET latin1 COLLATE latin1_bin

BINARY のカラム属性としての効果は、MySQL 4.1 より前の効果とは異なります。以前は、BINARY は、バイナリ文字列として扱われたカラムになっていました。バイナリ文字列は、文字セットや照合順序がないバイトの文字列であり、バイナリ照合順序を持つ非バイナリ文字列とは異なります。どちらのタイプの文字列についても、比較は文字列単位の数値に基づいて行われますが、非バイナリ文字列については、単位は文字であり、文字セットによってはマルチバイト文字をサポートします。セクション11.4.2「BINARY および VARBINARY 型」を参照してください。

CHARVARCHAR、または TEXT カラムの定義で CHARACTER SET binary を使用すると、このカラムはバイナリデータ型として扱われます。たとえば、次のペアになった定義は同等です。

CHAR(10) CHARACTER SET binary
BINARY(10)

VARCHAR(10) CHARACTER SET binary
VARBINARY(10)

TEXT CHARACTER SET binary
BLOB

User Comments
  Posted by Paul Masri on February 10, 2005
How to do a case sensitive search:

By default, in MySQL 4, text comparisons will be case-insensitive. e.g.
SELECT Name FROM namelist WHERE Name="Harry"
returns "Harry", "HARRY" and "harry"
because the default collation is case-insensitive - H is equivalent to h.

Using BINARY in the WHERE clause forces a match on the binary collation, which in English means that it matches actual characters by their character code, not by whether the characters are deemed equivalent.

Using the same example,
SELECT Name FROM namelist WHERE BINARY Name="Harry"
returns "Harry" only.

See also A.5.1
  Posted by Yann Neuhaus on July 20, 2005
Per default the search operation in not case sensitive, example, looking for 'HYPE BEAU' returns 'Hype Beau' in the table product :

mysql> select prod_name, prod_id from products where prod_name = 'HYPE BEAU';
+-----------+---------+
| prod_name | prod_id |
+-----------+---------+
| Hype Beau | 9600 |
| Hype Beau | 25860 |
| Hype Beau | 42120 |
| Hype Beau | 46185 |
+-----------+---------+
4 rows in set (0.01 sec)

This is because the default collation is case insentitive. With the binary clause the binary collation is used and the search becomes case sensitive :

mysql> select prod_name, prod_id from products where binary prod_name = 'HYPE BEAU';
Empty set (0.09 sec)

mysql> select prod_name, prod_id from products where binary prod_name = 'Hype Beau';
+-----------+---------+
| prod_name | prod_id |
+-----------+---------+
| Hype Beau | 9600 |
| Hype Beau | 25860 |
| Hype Beau | 42120 |
| Hype Beau | 46185 |
+-----------+---------+
4 rows in set (0.09 sec)

OK but the problem is that with binary, the index cannot be used :

mysql> explain select prod_name, prod_id from products where binary prod_name = 'Hype Beau';
+----+-------------+----------+------+---------------+------+---------+------+-------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------+------+---------------+------+---------+------+-------+-------------+
| 1 | SIMPLE | products | ALL | NULL | NULL | NULL | NULL | 10000 | Using where |
+----+-------------+----------+------+---------------+------+---------+------+-------+-------------+
1 row in set (0.00 sec)

The solution is to apply the binary operator to the constant, then the index is used :

mysql> select prod_name, prod_id from products where prod_name = binary 'Hype Beau';
+-----------+---------+
| prod_name | prod_id |
+-----------+---------+
| Hype Beau | 9600 |
| Hype Beau | 25860 |
| Hype Beau | 42120 |
| Hype Beau | 46185 |
+-----------+---------+
4 rows in set (0.00 sec)

mysql> explain select prod_name, prod_id from products where prod_name = binary 'Hype Beau';
+----+-------------+----------+-------+------------------------+------------------------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------+-------+------------------------+------------------------+---------+------+------+-------------+
| 1 | SIMPLE | products | range | products_prod_name_idx | products_prod_name_idx | 52 | NULL | 3 | Using where |
+----+-------------+----------+-------+------------------------+------------------------+---------+------+------+-------------+
1 row in set (0.00 sec)

Sign Up Login You must be logged in to post a comment.