O problema é que o MySQL ignora os espaços em branco ao fazer a comparação de strings. Consultehttp://dev.mysql.com/doc/refman/ 5.7/pt/char.html
(Esta informação é para 5.7; para 8.0 isso mudou, veja abaixo)
A seção para o
like
operador dá um exemplo para este comportamento (e mostra que like
respeita o espaço em branco à direita):mysql> SELECT 'a' = 'a ', 'a' LIKE 'a ';
+------------+---------------+
| 'a' = 'a ' | 'a' LIKE 'a ' |
+------------+---------------+
| 1 | 0 |
+------------+---------------+
1 row in set (0.00 sec)
Infelizmente, o
UNIQUE
index parece usar a comparação de string padrão para verificar se já existe tal valor e, portanto, ignora o espaço em branco à direita. Isso é independente do uso de VARCHAR
ou CHAR
, em ambos os casos a inserção é rejeitada porque a verificação exclusiva falha. Se houver uma maneira de usar like
semântica para o UNIQUE
verifique então eu não sei. O que você pode fazer é armazenar o valor como
VARBINARY
:mysql> create table test_ws ( `value` varbinary(255) UNIQUE );
Query OK, 0 rows affected (0.13 sec)
mysql> insert into test_ws (`value`) VALUES ('a');
Query OK, 1 row affected (0.08 sec)
mysql> insert into test_ws (`value`) VALUES ('a ');
Query OK, 1 row affected (0.06 sec)
mysql> SELECT CONCAT( '(', value, ')' ) FROM test_ws;
+---------------------------+
| CONCAT( '(', value, ')' ) |
+---------------------------+
| (a) |
| (a ) |
+---------------------------+
2 rows in set (0.00 sec)
É melhor você não querer fazer nada como classificar em ordem alfabética nesta coluna, porque a classificação acontecerá nos valores de byte, e isso não será o que os usuários esperam (a maioria dos usuários, pelo menos).
A alternativa é corrigir o MySQL e escrever seu próprio agrupamento que é do tipo NO PAD. Não tenho certeza se alguém quer fazer isso, mas se quiser, me avise;)
Edit:enquanto isso, o MySQL possui agrupamentos do tipo NO PAD, de acordo com https://dev.mysql.com/doc/refman/8.0/en/char.html :
e https://dev.mysql.com/ doc/refman/8.0/en/charset-unicode-sets.html
Então se você tentar:
create table test_ws ( `value` varbinary(255) UNIQUE )
character set utf8mb4 collate utf8mb4_0900_ai_ci;
você pode inserir valores com e sem espaço em branco à direita
Você pode encontrar todos os agrupamentos NO PAD disponíveis com:
show collation where Pad_attribute='NO PAD';