在mysql数据库系统中,char和varchar是非常常见的,它们两个也非常的相似,都是用来保存相对较短的字符串,如保存文章标题、留言、email、用户名等。
二者的主要区别在于存储方式:
char列长度是创建表时声明的长度而且固定不变,长度被限制在0到255之间。而varchar列中的值是可变长度字符串,长度也为0-255,在5.0.3之后长度延长到65535。
在查询显示数据的时候,char会删除字符串尾部的空格(仅仅是尾部),而varchar则完全保留这些空格。这样我们在显示char类型字符串时就没有必要trim掉尾部的空格了。
char适合与保存短字符内容,比如说是 "YS ", "AD ", "OK ", "NO ", "DL ",之类的标志控制符
用于检索方面的,但是前提是,必须是定长的字符才能够保证效率,
vchar适合保存容量较大的内容。不适合保存标志类信息,他的优势是节省存储空间。
为了提高效率吧vchar转传撑char没有什么意义
在MySQL中用来判断是否需要进行对据列类型转换的规则
1、在一个数据表里,如果每一个数据列的长度都是固定的,那么每一个数据行的长度也将是固定的.
2、只要数据表里有一个数据列的长度的可变的,那么各数据行的长度都是可变的.
3、如果某个数据表里的数据行的长度是可变的,那么,为了节约存储空间,MySQL会把这个数据表里的固定长度类型的数据列转换为相应的可变长度类型.
例外:长度小于4个字符的char数据列不会被转换为varchar类型
性能测试
VARCHAR平均长度200,CHAR长度250,其它配置如下:
配置项
配置
记录数
1000万,2000万,5000万,1亿
存储引擎
Innodb
行格式
compact
测试过程中使用的表结构
代码如下 | 复制代码 |
CREATE TABLE `mysqlchar` ( `username` char(32) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8; CREATE TABLE `mysqlchar` ( CREATE TABLE `mysqlchar` ( CREATE TABLE `mysqlchar` ( |
代码如下 | 复制代码 |
<?php function getRandom($length){ $str = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_1234567890'; $result = ''; for($i=$length;$i>0;$i--){ $result .= $str{mt_rand(0,62)}; } return $result; } function insert(){ $dsn = 'mysql:dbname=test;host=127.0.0.1'; $user = 'root'; $password = 'xxxxx'; $dbh = new PDO($dsn, $user, $password); $sth = $dbh->prepare('INSERT INTO mysqlchar(`username`) VALUES(?)'); echo microtime(); echo ' '; for($i=0;$i<20;$i++){ $sth->execute(array(getRandom(mt_rand(6,32)))); } echo microtime(); } function select(){ $dsn = 'mysql:dbname=test;host=127.0.0.1'; $user = 'root'; $password = 'xxxxxx'; $dbh = new PDO($dsn, $user, $password); $sth = $dbh->prepare('SELECT username from mysqlchar WHERE username = ?'); echo microtime(); echo ' '; $sth->execute(array('BOklEnL2onF')); echo microtime(); } function addKey(){ $dsn = 'mysql:dbname=test;host=127.0.0.1'; $user = 'root'; $password = 'xxxxx'; $dbh = new PDO($dsn, $user, $password); echo microtime(); echo ' '; $dbh->query('ALTER TABLE mysqlchar ADD KEY test(`username`)'); echo microtime(); } //insert(); //select(); //addKey(); ?> |
测试结果(单位:秒)
MyISAM | InnoDB | ||||
选项 | CHAR(32) | VARCHAR(32) | 选项 | CHAR(32) | VARCHAR(32) |
1、插入200W数据时间(PHP命令行下执行) | 443.34701 | 422.386431 | 1、插入1W数据时间(PHP命令行下执行) | 227.850326 | 215.932341 |
2、插入20条数据(三次平均) | 0.004720 | 0.004445 | 2、插入20条数据(三次平均) | 0.381118 | 0.405421 |
3、查询1条数据(三次平均) | 0.858885 | 0.827146 | 3、查询1条数据(三次平均) | 0.017053 | 0.011800 |
4、建立索引 | 30.322559 | 24.306851 | 4、建立索引 | 0.502228 | 0.455406 |
6、插入20条数据(三次平均) | 0.006587 | 0.006420 | 6、插入20条数据(三次平均) | 0.359265 | 0.418550 |
7、查询1条数据(三次平均) | 0.005637 | 0.002780 | 7、查询1条数据(三次平均) | 0.000867 | 0.000679 |
结果说明 | 在MyISAM引擎下,VARCHAR(32)在各方面的性能都比CHAR(32)较好。 在InnoDB引擎下,除了插入数据VARCHAR(32)的性能略输CHAR(32)外,在查询方面的性能均比CHAR(32)好。 |