Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Baza danych MySQL z unikalnymi polami ignorującymi końcowe spacje

Problem polega na tym, że MySQL ignoruje końcowe białe znaki podczas porównywania ciągów. Zobaczhttp://dev.mysql.com/doc/refman/ 5.7/pl/znak.html

(Te informacje dotyczą wersji 5.7; dla wersji 8.0 to się zmieniło, patrz poniżej)

Sekcja dla like operator podaje przykład tego zachowania (i pokazuje, że like uwzględnia końcowe białe znaki):

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

Niestety UNIQUE index wydaje się używać standardowego porównywania ciągów znaków, aby sprawdzić, czy istnieje już taka wartość, a zatem ignoruje końcowe białe znaki. Jest to niezależne od użycia VARCHAR lub CHAR , w obu przypadkach wstawienie jest odrzucane, ponieważ sprawdzanie unikatowe kończy się niepowodzeniem. Jeśli istnieje sposób na użycie like semantyka dla UNIQUE sprawdź to nie wiem.

Możesz zapisać wartość 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)

Lepiej nie chcieć robić nic takiego jak sortowanie alfabetyczne w tej kolumnie, ponieważ zamiast tego sortowanie nastąpi na wartościach bajtów, a to nie będzie to, czego oczekują użytkownicy (w każdym razie większość użytkowników).

Alternatywą jest załatanie MySQL i napisanie własnego zestawienia typu NO PAD. Nie jestem pewien, czy ktoś chce to zrobić, ale jeśli tak, daj mi znać;)

Edycja:w międzyczasie MySQL ma zestawienia typu NO PAD, zgodnie z https://dev.mysql.com/doc/refman/8.0/en/char.html :

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

Więc jeśli spróbujesz:

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

możesz wstawiać wartości z końcowymi białymi znakami i bez

Możesz znaleźć wszystkie dostępne zestawienia NO PAD z:

 show collation where Pad_attribute='NO PAD';


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Porównywanie dat w MySQL z pominięciem części czasu w polu DateTime

  2. Błąd tworzenia tabeli MySQL 5.5.9 i Hibernate na TYPE

  3. Jak mogę tymczasowo wyłączyć ograniczenie klucza obcego w MySQL?

  4. Jak wybrać polem binarnym? (php, mysql)

  5. Różnice w tygodniach między PHP a MySQL