在mysql數(shù)據(jù)庫系統(tǒng)中,char和varchar是非常常見的,它們兩個也非常的相似,都是用來保存相對較短的字符串,如保存文章標題、留言、email、用戶名等.
二者的主要區(qū)別在于存儲方式:
char列長度是創(chuàng)建表時聲明的長度而且固定不變,長度被限制在0到255之間。而varchar列中的值是可變長度字符串,長度也為0-255,在5.0.3之后長度延長到65535。
在查詢顯示數(shù)據(jù)的時候,char會刪除字符串尾部的空格(僅僅是尾部),而varchar則完全保留這些空格。這樣我們在顯示char類型字符串時就沒有必要trim掉尾部的空格了。
char適合與保存短字符內(nèi)容,比如說是 "YS ", "AD ", "OK ", "NO ", "DL ",之類的標志控制符用于檢索方面的,但是前提是,必須是定長的字符才能夠保證效率,
vchar適合保存容量較大的內(nèi)容。不適合保存標志類信息,他的優(yōu)勢是節(jié)省存儲空間。
為了提高效率吧vchar轉(zhuǎn)傳撐char沒有什么意義
在MySQL中用來判斷是否需要進行對據(jù)列類型轉(zhuǎn)換的規(guī)則:
1、在一個數(shù)據(jù)表里,如果每一個數(shù)據(jù)列的長度都是固定的,那么每一個數(shù)據(jù)行的長度也將是固定的.
2、只要數(shù)據(jù)表里有一個數(shù)據(jù)列的長度的可變的,那么各數(shù)據(jù)行的長度都是可變的.
3、如果某個數(shù)據(jù)表里的數(shù)據(jù)行的長度是可變的,那么,為了節(jié)約存儲空間,MySQL會把這個數(shù)據(jù)表里的固定長度類型的數(shù)據(jù)列轉(zhuǎn)換為相應(yīng)的可變長度類型.
例外:長度小于4個字符的char數(shù)據(jù)列不會被轉(zhuǎn)換為varchar類型
性能測試:VARCHAR平均長度200,CHAR長度250,其它配置如下:
配置項:配置
記錄數(shù):1000萬,2000萬,5000萬,1億
存儲引擎:Innodb
行格式:compact
測試過程中使用的表結(jié)構(gòu),代碼如下:
- 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(); //Vevb.com
- echo ' ';
- $dbh->query('ALTER TABLE mysqlchar ADD KEY test(`username`)');
- echo microtime();
- }
- //insert();
- //select();
- //addKey();
- ?>
測試結(jié)果(單位:秒)
MyISAM InnoDB
選項 CHAR(32) VARCHAR(32) 選項 CHAR(32) VARCHAR(32)
1、插入200W數(shù)據(jù)時間(PHP命令行下執(zhí)行) 443.34701 422.386431 1、插入1W數(shù)據(jù)時間(PHP命令行下執(zhí)行) 227.850326 215.932341
2、插入20條數(shù)據(jù)(三次平均) 0.004720 0.004445 2、插入20條數(shù)據(jù)(三次平均) 0.381118 0.405421
3、查詢1條數(shù)據(jù)(三次平均) 0.858885 0.827146 3、查詢1條數(shù)據(jù)(三次平均) 0.017053 0.011800
4、建立索引 30.322559 24.306851 4、建立索引 0.502228 0.455406
6、插入20條數(shù)據(jù)(三次平均) 0.006587 0.006420 6、插入20條數(shù)據(jù)(三次平均) 0.359265 0.418550
7、查詢1條數(shù)據(jù)(三次平均) 0.005637 0.002780 7、查詢1條數(shù)據(jù)(三次平均) 0.000867 0.000679
結(jié)果說明 在MyISAM引擎下,VARCHAR(32)在各方面的性能都比CHAR(32)較好。
在InnoDB引擎下,除了插入數(shù)據(jù)VARCHAR(32)的性能略輸CHAR(32)外,在查詢方面的性能均比CHAR(32)好。
新聞熱點
疑難解答
圖片精選