Mysql
 sql >> Datenbank >  >> RDS >> Mysql

MySQL-Datenbank mit eindeutigen Feldern ignoriert Leerzeichen am Ende

Das Problem ist, dass MySQL nachgestellte Leerzeichen beim String-Vergleich ignoriert. Siehe http://dev.mysql.com/doc/refman/ 5.7/en/char.html

(Diese Information gilt für 5.7; für 8.0 hat sich dies geändert, siehe unten)

Der Abschnitt für like Operator gibt ein Beispiel für dieses Verhalten (und zeigt, dass like respektiert nachgestellte Leerzeichen):

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

Leider der UNIQUE index scheint den Standard-String-Vergleich zu verwenden, um zu prüfen, ob es bereits einen solchen Wert gibt, und ignoriert daher nachgestellte Leerzeichen. Dies ist unabhängig von der Verwendung von VARCHAR oder CHAR , in beiden Fällen wird die Einfügung zurückgewiesen, weil die Eindeutigkeitsprüfung fehlschlägt. Wenn es eine Möglichkeit gibt, like zu verwenden Semantik für den UNIQUE überprüfen Sie, dann weiß ich es nicht.

Was Sie tun könnten, ist den Wert als VARBINARY zu speichern :

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)

Sie sollten diese Spalte besser nicht alphabetisch sortieren, da die Sortierung stattdessen nach den Bytewerten erfolgt, und das wird nicht das sein, was die Benutzer erwarten (zumindest die meisten Benutzer).

Die Alternative besteht darin, MySQL zu patchen und Ihre eigene Sortierung zu schreiben, die vom Typ NO PAD ist. Ich bin mir nicht sicher, ob das jemand machen möchte, aber wenn doch, lass es mich wissen;)

Bearbeiten:Mittlerweile hat MySQL Sortierungen vom Typ NO PAD, gemäß https://dev.mysql.com/doc/refman/8.0/en/char.html :

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

Also, wenn Sie es versuchen:

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

Sie können Werte mit und ohne Leerzeichen einfügen

Sie finden alle verfügbaren NO PAD-Sortierungen mit:

 show collation where Pad_attribute='NO PAD';