sql >> Databáze >  >> RDS >> Mysql

Databáze MySQL s jedinečnými poli ignorovala koncové mezery

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


  1. Jak nastavit replikaci MySQL v RHEL, Rocky a AlmaLinux

  2. tsql vrací tabulku z funkce nebo procedury úložiště

  3. Fulltextové vyhledávání MySQL proti hodnotě sloupce?

  4. Rozdíl mezi NOW(), SYSDATE() &CURRENT_DATE() v MySQL