Mysql
 sql >> Database >  >> RDS >> Mysql

Confrontando le stringhe con una che ha spazi vuoti prima mentre l'altra no

I tipi CHAR riempiono la stringa fino alla lunghezza del campo con byte nulli (mentre VARCHAR aggiunge delimitatori per indicare la fine della stringa, ignorando così i dati extra alla fine (Intendo byte vuoti )), e quindi i confronti che hanno spazi alla fine li ignoreranno. Gli spazi iniziali sono rilevanti in quanto alterano la stringa stessa. Vedi la risposta di Christopher.

EDIT:sono necessarie ulteriori elaborazioni

Vedi alcuni test pratici di seguito. I tipi VARCHAR aggiungono spazi alla stringa, mentre i campi CHAR, anche se riempiono la stringa fino alla sua dimensione di spazi, li ignorano durante i confronti. Vedi in particolare la seconda riga con LENGTH interrogazione della funzione:

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)

dove MySQL afferma che il campo CHAR, con il valore di 'a ' come è stato inserito, ha solo 1 carattere di lunghezza. Inoltre, se concateniamo un po' di dati:

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)

puoi vedere che, poiché VARCHAR memorizza dove finisce la stringa, lo spazio rimane sulle concatenazioni, il che non vale per i tipi CHAR. Ora, tenendo presente la precedente LENGTH esempio, dove la riga due ha lunghezze diverse per i suoi campi aeb, testiamo:

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

Pertanto, possiamo riassumere affermando che il tipo di dati CHAR ignora e riduce lo spazio extra alla fine della sua stringa, mentre VARCHAR no, tranne durante i confronti :

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)

Quindi, vale lo stesso per il tipo CHAR?

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)

Che mostra che i tipi CHAR e VARCHAR hanno metodi di archiviazione diversi, ma seguono le stesse regole per il semplice confronto delle stringhe . Gli spazi finali vengono ignorati; mentre gli spazi iniziali modificano la stringa stessa.