Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Banco de dados MySQL com campos exclusivos ignorados espaços finais


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';