CHAR types fill the string to the length of the field with null bytes (while VARCHAR add delimiters to indicate the end of the string - thus ignoring extra data at the end (I mean empty bytes)), and therefore comparisons that have spaces at the end will ignore those. Leading spaces are relevant as their alter the string itself. See Christopher's answer.
EDIT: some further elaboration required
See some practical tests below. VARCHAR types do add spaces to the string, whilst CHAR fields, even though they fill the string up to its size with spaces, ignore them during comparisons. See specifically the second line with the LENGTH
function query:
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)
where MySQL states the CHAR field, with the value of 'a ' as it was inserted, has only 1 character in length. Furthermore, if we concatenate a little data:
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)
you can see that, since VARCHAR does store where the string ends, the space remains on concatenations - which does not hold true for CHAR types. Now, keeping in mind the previous LENGTH
example, where line two has different lengths for its fields a and b, we test:
mysql> SELECT * FROM test WHERE a=b;
+------+------+
| a | b |
+------+------+
| a | a |
| a | a |
| a | a |
+------+------+
3 rows in set (0.00 sec)
Therefore, we can sum up stating that the CHAR datatype ignores and trims extra space at the end of its string, while VARCHAR does not - except during comparisons:
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)
So, is the same true for the CHAR type?
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)
Which displays that the CHAR and VARCHAR types have different storage methods, but follow the same rules for sheer string comparison. Trailing spaces are ignored; while leading spaces modify the string itself.