MySQL数据类型之char与varchar

    xiaoxiao2022-07-06  201

    测试环境:MySQL-5.7.17

    各位DBA同事及开发童鞋,相信你们看了这篇文章,会彻底明白char与varchar应该如何去选择使用。首先讲解一下char与varchar。 char(n):n的最大值为255 varchar(n):n的理论最大值65535,其实也就最多65532 这里需要注意,在mysql中n表示的是字符长度,即能插入n个字符,无论字母、数字、还是汉字,这一点与oracle是不一样,在oracle中n表示为字节长度,utf8的模式下一个汉字占3个字节,故oracle中的char(10),只能最多存3个汉字,MySQL的char(10)可以存储10个汉字。

    验证1,char(n)/varchar(n)中的n表示字符长度:下图超过2位就报错啦

    那么char与varchar到底如何选择呢?都知道一个是定长类型,一个是变长类型,在mysql中定长与变长到底是什么含义呢?先提出假设,定长即设定了char(10),那么哪怕你的数据没有10位,也会占用10的存储空间,若是varchar(10)则不会。实验验证:

    验证2: 建立两个表: [dba_yzy@localhost][test1]> create table zifu1(name char(5)); Query OK, 0 rows affected (0.80 sec)

    [dba_yzy@localhost][test1]> create table zifu2(name varchar(5)); Query OK, 0 rows affected (0.22 sec) 分别插入测试数据(下面执行32768次): [dba_yzy@localhost][test1]> insert into zifu1 values(‘12345’); Query OK, 1 row affected (0.02 sec)

    [dba_yzy@localhost][test1]> insert into zifu2 values(‘12345’); Query OK, 1 row affected (0.06 sec) 可以看到,两个表的字节大小是一样的

    现在我分别增大两个表的数据类型长度,从5加到15;存储的数据不动它。 [dba_yzy@localhost][test1]> alter table zifu1 modify name char(15); Query OK, 32768 rows affected (0.22 sec) Records: 32768 Duplicates: 0 Warnings: 0

    [dba_yzy@localhost][test1]> alter table zifu2 modify name varchar(15); Query OK, 0 rows affected (0.01 sec) Records: 0 Duplicates: 0 Warnings: 0 可以看到,两个表的字节大小不一样了,varchar没变,char变大了。

    好,证明了,char(n)类型是按照n指定的大小来分配的存储空间,而varchar(n),则是根据数据实际的长度来分配的。我们不管mysql中当char类型的数据长度达不到n时,会用什么去填充,这不重要,重要的是知道它确实会浪费存储空间了

    在实际生产中,各位开发童鞋为了省事,统统用varcahr,可以理解,因为能用到char类型的场景确实不多,一个固定长度的字段,如身份证号,用char(18)与varcahr(18)是一样的。并且在修改字段类型长度时,varchar列的加长在5.7中能做到秒级,char做不到。故为了统一、为了磁盘容量、为了提升变更速度,偏向于推荐使用varchar类型。但是在指定长度时不能太夸张,因为长度越大,会消耗更多的内存,MYSQL通常会分配固定大小的内存来保存内部值,浪费了一些内存的同时,在排序方面也会更加糟糕。

    这里我解释一下为何枚举类型字段不用char/varchar类型,假设有一个字段c1,目前取值:0、1、2,那么目前用char(1)是没问题,但是你能保证c1的可能值会达到10、11吗?不得不考虑它的扩展,有的人会说,那可以设为char(2)或者varchar(2),但我认为,都不如用tinyint好,空间小,范围大,nice!!!

    最新回复(0)