代码示例
length(字段):查看该字段数据的字节长度
char_length(字段):查看该字段数据的字符长度
创建一个t1表,包含一个char类型的字段
create table t1(id int,name char(4));
超过长度:
严格模式下(报错):
mysql> insert into t1 values('xiaoshabi');
ERROR 1406 (22001): Data too long for column 'name' at row 1
非严格模式下(警告):
mysql> set sql_mode='NO_ENGINE_SUBSTITUTION';
Query OK, 0 rows affected (0.00 sec)
mysql> create table t1(id int,name char(4));
Query OK, 0 rows affected (0.40 sec)
mysql> insert into t2 values('xiaoshabi');
Query OK, 1 row affected, 1 warning (0.11 sec)
查看一下结果:
mysql> select * from t1;
+------+------+
| id | name |
+------+------+
| 1 | xiao | #只有一个xiao
+------+------+
1 row in set (0.00 sec)
varchar类型和上面的效果是一样的,严格模式下也会报错。
如果没有超过长度,那么char类型时mysql会使用空格来补全自己规定的char(4)的4个字符,varchar不会,我们来做个对比
例如:
#再创建一个含有varchar类型的表t2
然后插入几条和t1里面相同的数据
mysql>insert into t1 values(2,'a'),(3,'bb'),(4,'ccc'),(5,'d');
mysql>create table t2(id int,name varchar(4));
mysql> insert into t2 values(1,'xiao'),(2,'a'),(3,'bb'),(4,'ccc'),(5,'d');
查看一下t1表和t2表的内容
mysql> select * from t1;
+------+------+
| id | name |
+------+------+
| 1 | xiao |
| 2 | a |
| 3 | bb |
| 4 | ccc |
| 5 | d |
+------+------+
5 rows in set (0.00 sec)
mysql> select * from t2;
+------+------+
| id | name |
+------+------+
| 1 | xiao |
| 2 | a |
| 3 | bb |
| 4 | ccc |
| 5 | d |
+------+------+
5 rows in set (0.00 sec)
好,两个表里面数据是一样的,每一项的数据长度也是一样的,那么我们来验证一下char的自动空格在后面补全的存储方式和varchar的不同
通过mysql提供的一个char_length()方法来查看一下所有数据的长度
mysql> select char_length(name) from t1;
+-------------------+
| char_length(name) |
+-------------------+
| 4 |
| 1 |
| 2 |
| 3 |
| 1 |
+-------------------+
5 rows in set (0.00 sec)
mysql> select char_length(name) from t2;
+-------------------+
| char_length(name) |
+-------------------+
| 4 |
| 1 |
| 2 |
| 3 |
| 1 |
+-------------------+
5 rows in set (0.00 sec)
通过查看结果可以看到,两者显示的数据长度是一样的,不是说好的char会补全吗,我设置的字段是char(4),那么长度应该都是4才对啊?这是因为mysql在你查询的时候自动帮你把结果里面的空格去掉了,如果我们想看到它存储数据的真实长度,需要设置mysql的模式,通过一个叫做PAD_CHAR_TO_FULL_LENGTH的模式,就可以看到了,所以我们把这个模式加到sql_mode里面:
mysql> set sql_mode='PAD_CHAR_TO_FULL_LENGTH';
Query OK, 0 rows affected (0.00 sec)
然后我们在查看一下t1和t2数据的长度:
mysql> select char_length(name) from t1;
+-------------------+
| char_length(name) |
+-------------------+
| 4 |
| 4 |
| 4 |
| 4 |
| 4 |
+-------------------+
5 rows in set (0.00 sec)
mysql> select char_length(name) from t2;
+-------------------+
| char_length(name) |
+-------------------+
| 4 |
| 1 |
| 2 |
| 3 |
| 1 |
+-------------------+
5 rows in set (0.00 sec)
通过结果可以看到,char类型的数据长度都是4,这下看到了两者的不同了吧,至于为什么mysql会这样搞,我们后面有解释的,先看现象就可以啦。
现在我们再来看一个问题,就是当你设置的类型为char的时候,我们通过where条件来查询的时候会有一个什么现象:
mysql> select * from t1 where name='a';
+------+------+
| id | name |
+------+------+
| 2 | a |
+------+------+
1 row in set (0.00 sec)
ok,结果没问题,我们在where后面的a后面加一下空格再来试试:
mysql> select * from t1 where name='a ';
+------+------+
| id | name |
+------+------+
| 2 | a |
+------+------+
1 row in set (0.00 sec)
ok,能查到,再多加一些空格试试,加6个空格,超过了设置的char(4)的4:
mysql> select * from t1 where name='a ';
+------+------+
| id | name |
+------+------+
| 2 | a |
+------+------+
1 row in set (0.00 sec)
ok,也是没问题的
总结:通过>,=,>=,
但是,当我们将where后面的比较符号改为like的时候,(like是模糊匹配的意思,我们前面见过,show variables like '%char%';来查看mysql字符集的时候用过)
其中%的意思是匹配任意字符(0到多个字符都可以匹配到),还有一个符号是_(匹配1个字符),这两个字符其实就像我们学的正则匹配里面的通配符,那么我们通过这些符号进行一下模糊查询,看一下,char类型进行模糊匹配的时候,是否还能行,看例子:
mysql> select * from t1 where name like 'a';
Empty set (0.00 sec)
发现啥也没查到,因为char存储的数据是4个字符长度的,不满4个是以空格来补全的,你在like后面就只写了一个'a',是无法查到的。
我们试一下上面的通配符来查询:
mysql> select * from t1 where name like 'a%';
+------+------+
| id | name |
+------+------+
| 2 | a |
+------+------+
1 row in set (0.00 sec)
这样就能看到查询结果了
试一下_是不是匹配1个字符:
mysql> select * from t1 where name like 'a_';
Empty set (0.00 sec)
发现一个_果然不行,我们试试三个_。
mysql> select * from t1 where name like 'a___';
+------+------+
| id | name |
+------+------+
| 2 | a |
+------+------+
1 row in set (0.00 sec)
发现果然能行,一个_最多匹配1个任意字符。
如果多写了几个_呢?
mysql> select * from t1 where name like 'a_____';
Empty set (0.00 sec)
查不到结果,说明_匹配的是1个字符,但不是0-1个字符。