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

Porovnávání řetězců s jedním, který má předtím prázdné mezery, zatímco druhý nikoli

Typy CHAR vyplní řetězec na délku pole prázdnými bajty (zatímco VARCHAR přidává oddělovače pro označení konce řetězce – čímž ignoruje další data na konci (Myslím prázdné bajty )), a proto srovnání, která mají na konci mezery, je budou ignorovat. Úvodní mezery jsou relevantní, protože mění samotný řetězec. Viz Christopherova odpověď.

UPRAVIT:Vyžaduje se další upřesnění

Podívejte se na několik praktických testů níže. Typy VARCHAR přidávají do řetězce mezery, zatímco pole CHAR, i když zaplňují řetězec až do jeho velikosti mezerami, je během porovnávání ignorují. Viz konkrétně druhý řádek s LENGTH funkční dotaz:

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)

kde MySQL uvádí, že pole CHAR s vloženou hodnotou 'a' má pouze 1 znak. Navíc, když zřetězíme málo dat:

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)

můžete vidět, že protože VARCHAR ukládá, kde končí řetězec, zůstává mezera na zřetězení - což neplatí pro typy CHAR. Nyní mějte na paměti předchozí LENGTH příklad, kde řádek dva má různé délky pro svá pole a a b, testujeme:

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

Můžeme tedy shrnout, že datový typ CHAR ignoruje a ořezává nadbytečné místo na konci svého řetězce, zatímco VARCHAR nikoli – kromě během porovnávání :

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)

Platí tedy totéž pro typ 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)

Což ukazuje, že typy CHAR a VARCHAR mají různé způsoby ukládání, ale dodržují stejná pravidla pro porovnání čistých řetězců . Koncové mezery jsou ignorovány; zatímco úvodní mezery upravují samotný řetězec.



  1. Funkce MAX() v PostgreSQL

  2. Problém s PHP a Mysql UTF-8 (speciální znak)

  3. Druh, který se rozlije na úroveň 15 000

  4. Jak se liší PostgreSQL od MySQL?