Problemet er, at MySQL ignorerer bagende mellemrum, når man laver strengsammenligning. Sehttp://dev.mysql.com/doc/refman/ 5.7/da/char.html
(Denne information er for 5.7; for 8.0 er dette ændret, se nedenfor)
Sektionen for like
operatoren giver et eksempel på denne adfærd (og viser, at like
respekterer efterstillede mellemrum):
mysql> SELECT 'a' = 'a ', 'a' LIKE 'a ';
+------------+---------------+
| 'a' = 'a ' | 'a' LIKE 'a ' |
+------------+---------------+
| 1 | 0 |
+------------+---------------+
1 row in set (0.00 sec)
Desværre er UNIQUE
indeks ser ud til at bruge standardstrengsammenligningen til at kontrollere, om der allerede er en sådan værdi, og ignorerer derfor efterstillede mellemrum. Dette er uafhængigt af brugen af VARCHAR
eller CHAR
, i begge tilfælde afvises indsættelsen, fordi den unikke kontrol mislykkes. Hvis der er en måde at bruge like
på semantik for UNIQUE
tjek så ved jeg det ikke.
Hvad du kan gøre er at gemme værdien som 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)
Du må hellere ikke gøre noget som at sortere alfabetisk på denne kolonne, fordi sortering vil ske på byte-værdierne i stedet, og det vil ikke være, hvad brugerne forventer (de fleste brugere i hvert fald).
Alternativet er at patche MySQL og skrive din egen kollation, som er af typen NO PAD. Ved ikke om nogen vil gøre det, men hvis du gør det, så lad mig det vide;)
Rediger:i mellemtiden har MySQL kollationer, som er af typen NO PAD, ifølge https://dev.mysql.com/doc/refman/8.0/en/char.html :
og https://dev.mysql.com/ doc/refman/8.0/da/charset-unicode-sets.html
Så hvis du prøver:
create table test_ws ( `value` varbinary(255) UNIQUE )
character set utf8mb4 collate utf8mb4_0900_ai_ci;
du kan indsætte værdier med og uden mellemrum
Du kan finde alle tilgængelige NO PAD-sammenstillinger med:
show collation where Pad_attribute='NO PAD';