この動作は設計によるものであり、MySQL だけのものではありません。
を使用して比較で回避できますBINARY
。
mysql> select version(), 'a' = 'a ', BINARY 'a' = BINARY 'a ';
+-------------+------------+--------------------------+
| version() | 'a' = 'a ' | BINARY 'a' = BINARY 'a ' |
+-------------+------------+--------------------------+
| 5.5.25a-log | 1 | 0 |
+-------------+------------+--------------------------+
1 row in set (0.00 sec)
しかし、それ以上ではありません。SELECT
これは、検索へのユーザー入力などに空白が表示される場合に役立ちます。しかし、実際に空白で追跡された情報を入力したい場合は、問題になります ('a' と 'a' の両方を含むインデックスを持つことはできません)。
こちらもご覧ください
比較のために、varchar の末尾の空白を考慮する必要があります。
おそらく、その列の文字列を逆にして、表示するときに元に戻すことができます。もちろん、これはその列に基づく順序付けを破壊しますが、同等性または部分文字列の存在のみをテストする場合は、うまくいく可能性があります。先頭のスペースはカウントされます。
等価検索の場合、文字列の base64 エンコーディングを格納することもできます。これは、辞書編集順序を維持する必要があります (つまり、a と b の間の順序は、base64(a) と base64(b) の間で維持する必要があります)。または、文字列にターミネータを追加することもできます (「\n」はうまく機能し、検索に表示されません)。
最後に、人間は違いを見分けられないため危険です。スペースを UTF8 文字 (49824) に置き換えることができます。
mysql> select concat ('\'a', char(49824),'\'') AS tricked,
concat ('\'a', ' ' ,'\'') as honest,
concat ('\'a', char(49824),'\'') =
concat ('\'a', ' ' ,'\'') as equals;
+---------+--------+--------+
| tricked | honest | equals |
+---------+--------+--------+
| 'a ' | 'a ' | 0 |
+---------+--------+--------+
1 row in set (0.00 sec)
行は等しいように見えますが、そうではありません。HTML ではスペースはスペースであり、49824 は
(ノンブレーク スペース) であることに注意してください。これは、HTML との間で変換する関数に影響を与えます。nbsp が実際には UTF8 コードポイントであることは、正直な文字列が 2 バイトであることを意味しますが、だまされた文字列の長さは実際には3です。
最後に、のVARBINARY
代わりに列を宣言できるVARCHAR
ため、何が起こっているかを完全に隠すことができます。これは最も簡単な解決策のように見えますが、数週間または数か月後には苦しむ可能性があるのではないかと心配しています.