Problém je v tom, že MySQL při porovnávání řetězců ignoruje koncové mezery. Vizhttp://dev.mysql.com/doc/refman/ 5.7/cs/char.html
(Tato informace je pro 5.7; pro 8.0 se to změnilo, viz níže)
Sekce pro like
operátor uvádí příklad tohoto chování (a ukazuje, že like
respektuje mezery na konci):
mysql> SELECT 'a' = 'a ', 'a' LIKE 'a ';
+------------+---------------+
| 'a' = 'a ' | 'a' LIKE 'a ' |
+------------+---------------+
| 1 | 0 |
+------------+---------------+
1 row in set (0.00 sec)
Bohužel UNIQUE
Zdá se, že index používá standardní porovnání řetězců ke kontrole, zda již taková hodnota existuje, a proto ignoruje koncové mezery. Toto je nezávislé na použití VARCHAR
nebo CHAR
, v obou případech je vložka zamítnuta, protože se nezdaří jednoznačná kontrola. Pokud existuje způsob, jak použít like
sémantiku pro UNIQUE
zkontrolujte, pak to nevím.
Co můžete udělat, je uložit hodnotu jako 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)
Raději nechtějte dělat nic takového, jako je řazení podle abecedy v tomto sloupci, protože řazení bude probíhat podle hodnot bajtů a to nebude to, co uživatelé očekávají (stejně většina uživatelů).
Alternativou je záplata MySQL a napsání vlastního řazení, které je typu NO PAD. Nejsem si jistý, jestli to někdo chce udělat, ale pokud ano, dejte mi vědět;)
Edit:mezitím má MySQL kolace, které jsou typu NO PAD, podle https://dev.mysql.com/doc/refman/8.0/en/char.html :
a https://dev.mysql.com/ doc/refman/8.0/en/charset-unicode-sets.html
Takže pokud to zkusíte:
create table test_ws ( `value` varbinary(255) UNIQUE )
character set utf8mb4 collate utf8mb4_0900_ai_ci;
můžete vkládat hodnoty s a bez koncových mezer
Všechny dostupné porovnávání NO PAD můžete najít pomocí:
show collation where Pad_attribute='NO PAD';