以下都是基于mysql5.0以上版本而言,也就是char和varchar括号内指定的都是最大字符数,话不多说先上结论:
行为 | char 字段 |
varchar 字段 |
---|---|---|
最大长度 | 255字符 | 括号中最大的字符数通过编码来算,不超过行65535个字节 |
是否定长 | 定长,不足的部分用隐藏空格填充 | 不定长,保留实际字符 |
空间使用 | 可能浪费 | 更加节省 |
查找效率 | 高 | 低 |
尾部空格 | 插入时省略 | 插入时不会省略,查找时可省略 |
like查找 | 语句中like后的’ '不会省 | 语句中like后的’ '不会省,字段结尾的空格也不会省 |
以上都是指严格模式下的情况,如果修改为宽松模式,插入时超过指定最大字符数会截取然后插入。具体改变宽松模式看:mysql修改sql_mode为宽松模式https://www.cnblogs.com/ningjiabing/p/12795338.html
测试一下是不是如结论,所说尾部空格,包括:长度查看、尾部空格、查询的测试
建立表tset_char_varchar
-----------建表------------
CREATE TABLE tset_char_varchar
(
id int PRIMARY KEY,
_char CHAR(10) DEFAULT NULL,
_varchar varchar(10) DEFAULT NULL
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4 COMMENT ='测试char和varchar区别表';
TRUNCATE tset_char_varchar;
-----------插入-------------
INSERT INTO
tset_char_varchar VALUE
(1, '123456', '123456'),
(2, '0123456789', '0123456789'),
(3, '一二三四五六七八九十', '一二三四五六七八九十');
-----------查询-------------
SELECT
_char,
CHAR_LENGTH(_char) char字符数,
LENGTH(_char) char字节数,
_varchar,
CHAR_LENGTH(_varchar) varchar字符数,
LENGTH(_varchar) varchar字节数
FROM
tset_char_varchar;
从上图可以看到插入不足10个字符、10个数字、十个汉字所对应的字符数和子节数,在这里还没看出差别。(当然如果插入的字符数>10会报错)
接下来测试一下带空格的数据
---为了查看方便把以上数据删除--
TRUNCATE tset_char_varchar;
-------插入数据------
INSERT INTO
tset_char_varchar
VALUES
(1, 'a', 'a'),
(2,' a',' a'),
(3,'a ','a '),
(4,' a ',' a ');
1为不带空格,2为左边带空格,3为右边带空格,4为两边都带空格
插入之后查看查询结果:
SELECT
_char,
CHAR_LENGTH(_char) char字符数,
LENGTH(_char) char字节数,
_varchar,
CHAR_LENGTH(_varchar) varchar字符数,
LENGTH(_varchar) varchar字节数
FROM
tset_char_varchar;
看第3、4条数据的字符数和字节数出现了不一致。
id=3存储的是只有右边有空格,那么varchar
把空格保留下来了,可以推断出id=4这条数据char
中缺失的就是右边空格所占的字节,如果不信的话,下面进行验证。
测试查询带空格的数据
_char
不带空格的结果:SELECT * FROM tset_char_varchar WHERE _char = 'a';
_char
左侧空格的结果:SELECT * FROM tset_char_varchar WHERE _char = ' a';
_char
右侧空格的结果:SELECT * FROM tset_char_varchar WHERE _char = 'a ';
结果什么都没有!
_char
两侧空格的结果:SELECT * FROM tset_char_varchar WHERE _char = ' a ';
结果什么都没有!
_varchar
结果:SELECT * FROM tset_char_varchar WHERE _varchar = 'a ';
SELECT * FROM tset_char_varchar WHERE _varchar = ' a';
SELECT * FROM tset_char_varchar WHERE _varchar = 'a ';
SELECT * FROM tset_char_varchar WHERE _varchar = ' a ';
具体图片不做赘述,这里每一条都只能查到唯一一条数据。
【结论】:char方式插入,右边有空格会自动过滤掉!!
以一个字符为例:
字符编码 | 英文字母(单位:byte) | 中文汉字(单位:byte) |
---|---|---|
ISO-8859-1 | 1 | 1 |
GB2312 | 1 | 2 |
GBK | 1 | 2 |
UTF-8 | 1 | 3 |
UTF-16 | 4 | 4 |
UTF-8字符编码的优势非常明显, 英文和数字(也就是ASCII字符集)只用一个byte, 而欧洲语言比如希腊语的字符占用2个byte,中文占用3个byte(超大字符集汉字占4个byte)。为了世界通用,所以后来像tomcat 8.x IDE等该用utf-8作为默认编码,也可以显示中文字符。
Mysql中char和varchar的区别:https://blog.csdn.net/albertsh/article/details/97501893
MySQL中varchar和char区别(转):https://www.cnblogs.com/webph/p/6679815.html
MySQL的char和varchar针对空格的处理:https://www.cnblogs.com/dsitn/p/7346761.html