sql >> Database >  >> RDS >> Mysql

MySQL-database met unieke velden negeerde eindspaties

Het probleem is dat MySQL de volgende witruimte negeert bij het vergelijken van strings. Ziehttp://dev.mysql.com/doc/refman/ 5.7/nl/char.html

(Deze informatie is voor 5.7; voor 8.0 is dit gewijzigd, zie hieronder)

De sectie voor de like operator geeft een voorbeeld voor dit gedrag (en laat zien dat like respecteert de volgende witruimte):

mysql> SELECT 'a' = 'a ', 'a' LIKE 'a ';
+------------+---------------+
| 'a' = 'a ' | 'a' LIKE 'a ' |
+------------+---------------+
|          1 |             0 |
+------------+---------------+
1 row in set (0.00 sec)

Helaas is de UNIQUE index lijkt de standaard tekenreeksvergelijking te gebruiken om te controleren of er al een dergelijke waarde is, en negeert dus de volgende witruimte. Dit is onafhankelijk van het gebruik van VARCHAR of CHAR , in beide gevallen wordt de insert afgewezen, omdat de unieke controle mislukt. Als er een manier is om like . te gebruiken semantiek voor de UNIQUE check dan weet ik het niet.

Wat je zou kunnen doen is de waarde opslaan als 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)

U kunt beter niets doen zoals alfabetisch sorteren op deze kolom, omdat het sorteren in plaats daarvan op de bytewaarden zal gebeuren, en dat is niet wat de gebruikers verwachten (in ieder geval de meeste gebruikers).

Het alternatief is om MySQL te patchen en uw eigen verzameling te schrijven die van het type NO PAD is. Ik weet niet zeker of iemand dat wil doen, maar als je dat doet, laat het me weten;)

Bewerken:ondertussen heeft MySQL sorteringen van het type NO PAD, volgens https://dev.mysql.com/doc/refman/8.0/en/char.html :

en https://dev.mysql.com/ doc/refman/8.0/en/charset-unicode-sets.html

Dus als je het probeert:

  create table test_ws ( `value` varbinary(255) UNIQUE )
    character set utf8mb4 collate utf8mb4_0900_ai_ci;

u kunt waarden invoegen met en zonder achterliggende witruimte

U kunt alle beschikbare NO PAD-verzamelingen vinden met:

 show collation where Pad_attribute='NO PAD';


  1. MySQL, ORDER BY invoegvolgorde, geen sorteerkolommen

  2. Verwijder alle spaties uit een string in SQL Server

  3. Tekencoderingsprobleem

  4. Python en Django OperationalError (2006, 'MySQL-server is verdwenen')