破いて捨てたノート

Webやテクノロジーやそれ以外に関する思いつき

【MySQL】MySQLはtrailing spaceを無視する【クソ仕様】

まずはこのコードを見てください。

User.where(user_name: 'yachibit ')
  User Load (0.5ms)  SELECT `users`.* FROM `users` WHERE `users`.`user_name` = 'yachibit '
=> [#<User id: 1, first_name: "Bit", last_name: "Yachi", user_name: "yachibit", ... >]

予想として、'yachibit'さんは存在しますが、'yachibit 'さんはいないので、レコードが見つからないことを想定していました。 しかし実際は違いました。

誰だ、意味不明なことを言うやつはー。と調べてみたところどうやらMySQLさんが犯人だったようです。

Values in CHAR and VARCHAR columns are sorted and compared according to the character set collation assigned to the column. All MySQL collations are of type PADSPACE. This means that all CHAR, VARCHAR, and TEXT values in MySQL are compared without regard to any trailing spaces.

http://dev.mysql.com/doc/refman/5.5/en/char.html

だそうです。 実験してみるとこんな感じ、

mysql> select 'yachibit' = 'yachibit ';
+--------------------+
| 'yachibit' = 'yachibit ' |
+--------------------+
|                  1 |
+--------------------+

mysql> select 'yachibit' = ' yachibit';
+--------------------+
| 'yachibit' = ' yachibit' |
+--------------------+
|                  0 |
+--------------------+

うーん、意味不明だな。

そして、そういうtrailing spaceを無視しないexact matchをしたかったらlikeを使えばいいらしい。

mysql> select 'yachibit' like 'yachibit ';
+-----------------------+
| 'yachibit' like 'yachibit ' |
+-----------------------+
|                     0 |
+-----------------------+

うーん。

実践ハイパフォーマンスMySQL 第3版

実践ハイパフォーマンスMySQL 第3版