Char屬于固定長度的字元類型,而varchar屬于可變長的字元類型。
下表将各種字元串值儲存到char(4)和varchar(4)列後的結果,說明了char和varchar之間的差别
值
Char(4)
存儲需求
Varchar (4)
‘’
‘ ’
4字元節
1字元節
‘ab’
‘ab ’
‘ab ’
3字元節
‘abcd’
5字元節
‘abcdefgh’
請注意,最後一行的值隻适用于非“嚴格模式”時,如果mysql運作在嚴格模式,超過列長度的值将不會儲存,并且會出現錯誤提示。
從char(4)和varchar(4)列檢索的值并不總是相同,因為檢索事從char列删除了尾部的空格。
由于char是固定長度的,是以他的處理速度比varhcar快的多,但是其缺點是浪費存儲空間,程式需要對尾行空格進行處理,是以對于哪些長度變化不大并且對查詢速度要求較高的資料可以考慮使用char類型存儲
另外,随着mysql版本的不斷更新,varchar資料類型的性能也在不斷改進并提高,是以在許多應用中,varvhar類型被更多使用
在mysql中,不同的存儲引擎對char和varchar的使用原則有所不同,這裡簡單概括若下:
Myisam存儲引擎:建議使用固定長度的資料列代替可變長的資料列
Memory存儲引擎:目前都使用固定長度的資料行存儲,是以無論使用char varchar列都沒有關系,兩者都是作為char類型處理
Innodb存儲引擎:建議使用varchar類型。對于innodb資料表,内部的行存儲格式沒有區分固定長度和可變長度列(所有資料行都使用指向資料列值的頭指針),是以在本質上,使用固定長度的char列不一定比使用可變長度varchar的性能要好,是以,主要的性能因素是資料行使用的存儲總量,由于char平均占用的空間多于varchar,是以使用varchar來最小化需要處理的資料行的存儲總量和磁盤I/O是比較好的。
上面來自網易《深入淺出MYSQL資料庫開發、優化與管理維護》
以下是測試過程,針對MYISAM,5.5.19 MySQL Community Server (GPL):
表結構
<a target="_blank" href="http://blog.51cto.com/attachment/201204/173631201.jpg"></a>
插入100萬條記錄
DELIMITER $$
USE `test`$$
DROP PROCEDURE IF EXISTS `test1`$$
CREATE DEFINER=`admin`@`%` PROCEDURE `test1`()
BEGIN
DECLARE i INT DEFAULT 1;
WHILE i <= 1000000 DO
INSERT INTO test1 VALUES (i,i,'abc');
SET i=i+1;
END WHILE;
END$$
DELIMITER ;
DROP PROCEDURE IF EXISTS `test2`$$
CREATE DEFINER=`admin`@`%` PROCEDURE `test2`()
INSERT INTO test2 VALUES (i,i,'abc');
[root@vm01 test]# ll -h |grep test
-rw-rw---- 1 mysql mysql 8.5K 04-01 17:16 test1.frm
-rw-rw---- 1 mysql mysql 19M 04-01 17:20 test1.MYD
-rw-rw---- 1 mysql mysql 17M 04-01 17:20 test1.MYI
-rw-rw---- 1 mysql mysql 8.5K 04-01 17:16 test2.frm
-rw-rw---- 1 mysql mysql 20M 04-01 17:26 test2.MYD
-rw-rw---- 1 mysql mysql 12M 04-01 17:26 test2.MYI
char表資料+主鍵+索引=19M+17M=36M
varchar表資料+主鍵+索引=20M+12M=32M
=====================================================================
下面測試不帶索引的。
<a href="http://blog.51cto.com/attachment/201204/174525458.jpg" target="_blank"></a>
-rw-rw---- 1 mysql mysql 8.5K 04-01 17:44 test1.frm
-rw-rw---- 1 mysql mysql 19M 04-01 18:01 test1.MYD
-rw-rw---- 1 mysql mysql 9.8M 04-01 18:01 test1.MYI
-rw-rw---- 1 mysql mysql 8.5K 04-01 17:44 test2.frm
-rw-rw---- 1 mysql mysql 20M 04-01 18:04 test2.MYD
-rw-rw---- 1 mysql mysql 9.9M 04-01 18:04 test2.MYI
char表資料+主鍵=19M+9.8M=28.8M
varchar表資料+主鍵=20M+9.9M=29.9M
下面測試不帶主鍵和索引的。
<a href="http://blog.51cto.com/attachment/201204/180911146.jpg" target="_blank"></a>
[root@vm01 test]# ll -h | grep test
-rw-rw---- 1 mysql mysql 8.5K 04-01 18:08 test1.frm
-rw-rw---- 1 mysql mysql 19M 04-01 18:10 test1.MYD
-rw-rw---- 1 mysql mysql 1.0K 04-01 18:10 test1.MYI
-rw-rw---- 1 mysql mysql 8.5K 04-01 18:08 test2.frm
-rw-rw---- 1 mysql mysql 20M 04-01 18:11 test2.MYD
-rw-rw---- 1 mysql mysql 1.0K 04-01 18:11 test2.MYI
char表資料=19M
varchar表資料=20M
總結:針對MYISAM引擎,如果使用varchar字元類型,增加索引的容量要小于不加索引的。
本文轉自 liang3391 51CTO部落格,原文連結:http://blog.51cto.com/liang3391/823326