search
LoginSignup
5

More than 1 year has passed since last update.

posted at

updated at

Organization

MySQLのchar,varcharは大文字小文字を区別しない

知ってる人には当たり前ですが、今更になってこれを知ったので書く。

とりあえず検証用MySQLを作成

dockerでやる

docker run --name test-mysql -e MYSQL_ROOT_PASSWORD=passwd -d mysql:8.0

dockerコンテナに入る

docker exec -it test-mysql bash

MySQLクライアントに接続する

mysql -u root -p

データベースを作る

mysql> create database if not exists test_db;
Query OK, 1 row affected (0.01 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| test_db            |
+--------------------+
5 rows in set (0.00 sec)

mysql> use test_db;
Database changed

とりあえずデフォルトの文字コードを確認する

mysql> select SCHEMA_NAME, DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME from INFORMATION_SCHEMA.SCHEMATA where SCHEMA_NAME='test_db';
+-------------+----------------------------+------------------------+
| SCHEMA_NAME | DEFAULT_CHARACTER_SET_NAME | DEFAULT_COLLATION_NAME |
+-------------+----------------------------+------------------------+
| test_db     | utf8mb4                    | utf8mb4_0900_ai_ci     |
+-------------+----------------------------+------------------------+

検証用テーブルを作る

varcharvarbinary型のカラムを作る。
それぞれに
test, Test, TESTという文字列を入れました。

mysql> create table test (txt_varchar varchar(255), txt_varbinary varbinary(255));
Query OK, 0 rows affected (0.04 sec)

mysql> insert into test values ('test', 'test'), ('TEST', 'TEST'), ('Test', 'Test');
Query OK, 3 rows affected (0.01 sec)
Records: 3  Duplicates: 0  Warnings: 0

大文字小文字が区別されない例

txt_varcharカラムに対してtestで検索してみます。

mysql> select * from test where txt_varchar = 'test';
+-------------+------------------------------+
| txt_varchar | txt_varbinary                |
+-------------+------------------------------+
| test        | 0x74657374                   |
| TEST        | 0x54455354                   |
| Test        | 0x54657374                   |
+-------------+------------------------------+
3 rows in set (0.01 sec)

全部引っかかりました。

大文字小文字が区別される例

binary型で作成したtxt_varbinaryカラムに対してtestで検索してみます。

mysql> select * from test where txt_varbinary = 'test';
+-------------+------------------------------+
| txt_varchar | txt_varbinary                |
+-------------+------------------------------+
| test        | 0x74657374                   |
+-------------+------------------------------+
1 row in set (0.01 sec)

無事、完全一致の文字列が検索されました。
ちなみにこれは解決方法ではなく、デフォルトのchar, varcharでは大文字小文字は区別されない例としてあげただけです。

解決方法

BINARY演算子を使う

varchar型に対して検索をする際にBINARY演算子をつけると大文字小文字を区別して検索してくれます。

mysql> select * from test where txt_varchar = binary 'test';
+-------------+------------------------------+
| txt_varchar | txt_varbinary                |
+-------------+------------------------------+
| test        | 0x74657374                   |
+-------------+------------------------------+
1 row in set (0.00 sec)

char, varcharに対してbinary属性をつける

binary属性を付与してみます。

mysql> alter table test modify txt_varchar varchar(255) binary;
Query OK, 0 rows affected, 1 warning (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 1

大文字小文字が区別されました。

mysql> select * from test where txt_varchar = 'test';
+-------------+------------------------------+
| txt_varchar | txt_varbinary                |
+-------------+------------------------------+
| test        | 0x74657374                   |
+-------------+------------------------------+
1 row in set (0.00 sec)

参考
B.5.5.1 文字列検索での大文字/小文字の区別

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
5