LoginSignup
14
8

More than 3 years have passed since last update.

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

Last updated at Posted at 2020-06-30

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

とりあえず検証用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 文字列検索での大文字/小文字の区別

14
8
0

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
  3. You can use dark theme
What you can do with signing up
14
8