在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` ( `username` varchar(32) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8; CREATE TABLE `mysqlchar` ( `username` char(32) default NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `mysqlchar` ( `username` varchar(32) default NULL ) ENGINE= InnoDB DEFAULT CHARSET |
| 代碼如下 |
複製代碼 |
<?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)好。 |