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

Vergleichen von Zeichenfolgen mit einer mit Leerzeichen, während die andere dies nicht tut

CHAR-Typen füllen den String bis zur Länge des Feldes mit Nullbytes auf (während VARCHAR Trennzeichen hinzufügt, um das Ende der Zeichenfolge anzuzeigen - wodurch zusätzliche Daten am Ende ignoriert werden (ich meine leere Bytes )), daher werden Vergleiche mit Leerzeichen am Ende diese ignorieren. Führende Leerzeichen sind relevant, da sie die Zeichenfolge selbst ändern. Siehe Christophers Antwort.

EDIT:einige weitere Ausarbeitung erforderlich

Sehen Sie unten einige praktische Tests. VARCHAR-Typen fügen dem String Leerzeichen hinzu, während CHAR-Felder, obwohl sie den String bis zu seiner Größe mit Leerzeichen füllen, sie bei Vergleichen ignorieren. Siehe speziell die zweite Zeile mit der LENGTH Funktionsabfrage:

mysql> create table test (a VARCHAR(10), b CHAR(10));
Query OK, 0 rows affected (0.17 sec)

mysql> insert into test values ('a', 'a'), ('a ', 'a '), (' a', ' a');
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> select a, LENGTH(a), b, LENGTH(b) FROM test;
+------+-----------+------+-----------+
| a    | LENGTH(a) | b    | LENGTH(b) |
+------+-----------+------+-----------+
| a    |         1 | a    |         1 | 
| a    |         2 | a    |         1 | 
|  a   |         2 |  a   |         2 | 
+------+-----------+------+-----------+
3 rows in set (0.00 sec)

wobei MySQL angibt, dass das CHAR-Feld mit dem Wert 'a', wie es eingefügt wurde, nur 1 Zeichen lang ist. Außerdem, wenn wir ein paar Daten verketten:

mysql> select CONCAT(a, '.'), CONCAT(b, '.') FROM test;
+----------------+----------------+
| CONCAT(a, '.') | CONCAT(b, '.') |
+----------------+----------------+
| a.             | a.             | 
| a .            | a.             | 
|  a.            |  a.            | 
+----------------+----------------+
3 rows in set (0.00 sec)

mysql> select CONCAT(a, b), CONCAT(b, a) FROM test;
+--------------+--------------+
| CONCAT(a, b) | CONCAT(b, a) |
+--------------+--------------+
| aa           | aa           | 
| a a          | aa           | 
|  a a         |  a a         | 
+--------------+--------------+
3 rows in set (0.00 sec)

Sie können sehen, dass das Leerzeichen bei Verkettungen verbleibt, da VARCHAR dort speichert, wo die Zeichenfolge endet - was für CHAR-Typen nicht gilt. Denken Sie jetzt an die vorherige LENGTH Wenn beispielsweise Zeile zwei unterschiedliche Längen für die Felder a und b hat, testen wir:

mysql> SELECT * FROM test WHERE a=b;
+------+------+
| a    | b    |
+------+------+
| a    | a    | 
| a    | a    | 
|  a   |  a   | 
+------+------+
3 rows in set (0.00 sec)

Daher können wir zusammenfassend feststellen, dass der CHAR-Datentyp zusätzliche Leerzeichen am Ende seiner Zeichenfolge ignoriert und abschneidet, während VARCHAR dies nicht tut - außer während Vergleichen :

mysql> select a from test where a = 'a ';
+------+
| a    |
+------+
| a    | 
| a    | 
+------+
2 rows in set (0.00 sec)

mysql> select a from test where a = 'a';
+------+
| a    |
+------+
| a    | 
| a    | 
+------+
2 rows in set (0.00 sec)

mysql> select a from test where a = ' a';
+------+
| a    |
+------+
|  a   | 
+------+
1 row in set (0.00 sec)

Gilt das also auch für den CHAR-Typ?

mysql> select a from test where b = 'a ';
+------+
| a    |
+------+
| a    | 
| a    | 
+------+
2 rows in set (0.00 sec)

mysql> select a from test where b = 'a';
+------+
| a    |
+------+
| a    | 
| a    | 
+------+
2 rows in set (0.00 sec)

mysql> select a from test where b = ' a';
+------+
| a    |
+------+
|  a   | 
+------+
1 row in set (0.00 sec)

Dies zeigt, dass die Typen CHAR und VARCHAR unterschiedliche Speichermethoden haben, aber denselben Regeln für den reinen Zeichenfolgenvergleich folgen . Nachfolgende Leerzeichen werden ignoriert; während führende Leerzeichen den String selbst modifizieren.