Esse comportamento ocorre por design, não apenas no MySQL.
Você pode contornar isso em comparações usando
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)
mas não muito mais. Isso irá ajudá-lo com
SELECT
s se aparecerem espaços em branco, por exemplo. na entrada do usuário para uma pesquisa; mas se você quiser realmente inserir informações com espaço em branco, será um problema (você não pode ter um índice com 'a' e 'a '). Veja também
Espaço em branco à direita em necessidades de varchar a ser considerado em comparação
Você poderia inverter as strings nessa coluna e reverta-as ao exibi-las. É claro que isso destruirá qualquer ordenação com base nessa coluna, mas se você testar apenas a igualdade ou a existência de substring, pode funcionar. Liderando os espaços contam.
Para pesquisas de igualdade, você também pode armazenar a codificação base64 da string, que deve manter a ordem lexicográfica (ou seja, a ordem entre a e b deve ser mantida entre base64(a) e base64(b)). Ou você pode anexar um terminador na string ("\n" pode funcionar bem e não aparecer nas pesquisas).
Finalmente, mas é arriscado porque os humanos não podem dizer a diferença, você pode substituir os espaços pelo caractere 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)
As linhas parecem serem iguais, mas não são. Observe que em HTML o espaço é um espaço e 49824 é
(Espaço inquebrável). Isso afeta funções que convertem de e para HTML, e o nbsp sendo na verdade um codepoint UTF8 significa que honesto string é de dois bytes, mas comprimento de enganado string é na verdade três . Finalmente você pode declarar a coluna
VARBINARY
em vez de VARCHAR
, ocultando completamente o que está acontecendo. Parece a solução mais fácil, mas temo que possa mordê-lo em algumas semanas ou meses.