字符串型
Char
定长字符:指定长度之后,系统一定会分配指定的空间用于存储数据.超过的长度的字段则只能截取出对应的长度进行存储,相对于要求字长长度不够的字段则用空格补齐。
基本语法:char(L),L代表字符数(中文与英文字母一样),L长度为0到255
Varchar
变长字符:指定长度之后,系统会根据实际存储的数据来计算长度,分配合适的长度(数据没有超出长度).规定字长之内,有多少存多少,无需补齐;超出的部分和char一样,截取出对应的长度进行存储。
基本语法:Varchar(L),L代表字符数,L的长度理论值为0到65535,因起始位和结束位占去了2-3个字节,所以其整体最大长度为65532-65533字节
因为varchar要记录数据长度(系统根据数据长度自动分配空间),所以每个varchar数据产生后,系统都会在数据后面增加1-2个字节的额外开销,是用来保存数据所占用的空间长度,如果数据本身小于127个字符,额外开销一个字节;如果大于127个,就开销两个字节。
注意:char 和 varchar 后面的长度表示字符不是字节数。
比如:定义一个char[10]和varchar[10],如果存进去的是‘csdn’,那么char所占的长度依然为10,除了字符‘csdn’外,后面跟六个空格,而varchar就立马把长度变为4了,取数据的时候,char类型的要用trim()去掉多余的空格,而varchar是不需要的。尽管如此,char的存取数度还是要比varchar要快得多,因为其长度固定,方便程序的存储与查找;但是char也为此付出的是空间的代价,因为其长度固定,所以难免会有多余的空格占位符占据空间,可谓是以空间换取时间效率,而varchar是以空间效率为首位的。
存储数据 | char(2) | varchar(2) | char所占字节 | varchar所占字节 |
A | A | A | 2*3=6 | 1*3+1=4 |
AB | AB | AB | 2*3=6 | 2*3+1=7 |
char和varchar的特点:
varchar:
1、使用比固定长度类型(char)占用更少存储空间(除了使用ROW_FORMAT=FIXED创建的MyISAM表)。
2、使用额外的1-2字节来存储值长度,列长度<=255使用1字节保存,其它情况使用2字节保存。例如varchar(10)会占用11字节存储空间,varchar(500)会占用502字节存储空间。
3、节约空间,所以性能会有帮助。在更新的时候会产生额外的工作。
4、5.0以上版本,取值或设置值都会保存字符串末尾的空格,4.1之前的版本都会把字符串末尾的空格删除掉。
5、最大长度远大于平均长度,很少发生更新的时候适合使用varchar,因为碎片更少了。
char:
1、使用固定长度。
2、保存的时候会去掉字符串末尾的空格。
3、适合保存MD5后的哈希值或经常改变的值,因为固定的行不容易产生碎片。
mysql> desc char_data;
+---------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| name | char(3) | YES | | NULL | |
| address | varchar(20) | YES | | NULL | |
+---------+-------------+------+-----+---------+-------+
2 rows in set (0.02 sec)
mysql> insert into char_data values(' 张三',' 北京市');
Query OK, 1 row affected (1.71 sec)
mysql> insert into char_data values('李四 ','南京市 ');
Query OK, 1 row affected (0.00 sec)
mysql> insert into char_data values('王 五','上海 市');
Query OK, 1 row affected (0.00 sec)
mysql> select * from char_data;
+-------+---------+
| name | address |
+-------+---------+
| 张三 | 北京市 |
| 李四 | 南京市 |
| 王 五 | 上海 市 |
+-------+---------+
3 rows in set (0.00 sec)
mysql> select concat("'",name,"'") from char_data;
+----------------------+
| concat("'",name,"'") |
+----------------------+
| ' 张三' |
| '李四' |
| '王 五' |
+----------------------+
3 rows in set (1.56 sec)
mysql> select concat("'",address,"'") from char_data;
+-------------------------+
| concat("'",address,"'") |
+-------------------------+
| ' 北京市' |
| '南京市 ' |
| '上海 市' |
+-------------------------+
3 rows in set (0.00 sec)
char和varchar的区别:
1、char一定会使用指定的空间,varchar是根据数据来定空间。
2、char的数据查询效率比varchar高,varchar是需要通过后面的记录数来计算存储长度,会浪费精力,而char是不需要的
适用情况:
1、对于MyISAM表,尽量使用Char,对于那些经常需要修改而容易形成碎片的myisam和isam数据表就更是如此,它的缺点就是占用磁盘空间;
2、对于InnoDB表,因为它的数据行内部存储格式对固定长度的数据行和可变长度的数据行不加区分(所有数据行共用一个表头部分,这个标头部分存放着指向各有关数据列的指针),所以使用char类型不见得会比使用varchar类型好。事实上,因为char类型通常要比varchar类型占用更多的空间,所以从减少空间占用量和减少磁盘i/o的角度,使用varchar类型反而更有利;
3、存储很短的信息,比如门牌号码101,201……这样很短的信息应该用char,因为varchar还要占个byte用于存储信息长度,本来打算节约存储的现在得不偿失。
4、固定长度的。比如使用uuid作为主键,那用char应该更合适。因为他固定长度,varchar动态根据长度的特性就消失了,而且还要占个长度信息。
5、十分频繁改变的column。因为varchar每次存储都要有额外的计算,得到长度等工作,如果一个非常频繁改变的,那就要有很多的精力用于计算,而这些对于char来说是不需要的。