Типы CHAR заполняют строку до длины поля нулевыми байтами (в то время как VARCHAR добавляет разделители для обозначения конца строки - таким образом игнорируя дополнительные данные в конце ( Я имею в виду пустое байты )), и поэтому сравнения, в конце которых есть пробелы, будут игнорироваться. Ведущие пробелы важны, поскольку они изменяют саму строку. Смотрите ответ Кристофера.
РЕДАКТИРОВАТЬ: требуется дополнительная доработка
См. Некоторые практические тесты ниже. Типы VARCHAR добавляют пробелы к строке, в то время как поля CHAR, даже если они заполняют строку до ее размера пробелами, игнорируют их при сравнении. Смотрите конкретно вторую строку с запросом функции LENGTH
:
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)
где MySQL сообщает поле CHAR со значением «a», как оно было вставлено, длиной всего 1 символ. Кроме того, если мы объединяем немного данных:
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)
вы можете видеть, что, поскольку VARCHAR сохраняет место, где заканчивается строка, пространство остается на конкатенациях - что не относится к типам CHAR. Теперь, помня предыдущий пример LENGTH
, где строка два имеет разную длину для своих полей a и b, мы тестируем:
mysql> SELECT * FROM test WHERE a=b;
+------+------+
| a | b |
+------+------+
| a | a |
| a | a |
| a | a |
+------+------+
3 rows in set (0.00 sec)
Таким образом, мы можем подвести итог, заявив, что тип данных CHAR игнорирует и обрезает дополнительный пробел в конце своей строки, а VARCHAR - нет, за исключением во время сравнений :
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)
То же самое относится и к типу 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)
Показывает, что типы CHAR и VARCHAR имеют разные методы хранения, но следуют тем же правилам для простого сравнения строк . Конечные пробелы игнорируются; в то время как начальные пробелы изменяют саму строку.