CHAR 與 VARCHAR的區別

2021-08-03 03:10:15 字數 3190 閱讀 1281

為什麼要談char與varchar?

大家可能想char和varchar這種東西再簡單不過了,只不過是mysql中最基本的資料型別,有什麼好深究的。其實有時候越簡單、越基礎的東西越複雜,越難以捉摸。

大家在使用mysql建立資料表時都會遇到這樣的問題,如何為字段選擇合適的資料型別,熟悉這些基本資料型別將會讓你從容地應對,做到建表時的優化。今天我們就來**一下mysql中的char和varchar。

先來熱熱身

char和varchar型別相似,都用來儲存字串,但是它們的儲存和檢索方式不同,在允許的最大長度和是否保留尾部空格上也有差異。

其中最重要的區別就是char是定長的字元型別,而varchar屬於變長的字元型別。

那麼什麼時候使用char,什麼時候使用varchar,別急,我們繼續下去就知道了。

開始我們的征途

主持人:今天我們有幸請來了mysql家族中的兩位大拿來到現場,大家猜猜他們是誰呢?(一陣等待,音調提高)他們分別是char與varchar,大家掌聲歡迎他們進場。(雷鳴般的掌聲)

char和varchar(異口同聲):謝謝主持人,謝謝觀眾朋友!

主持人:眾所周知,人們經常濫用混用你們兩位(char和varchar一副贊同臉)。今天也有幸請到了你們二位,也希望作為當事人的你們給大家乙個完美的闡述。

varchar:主持人,你的此番言語可謂是觸動了我和char兩兄弟的內心深處的那根弦(感動的樣子)。我用來儲存可變長字串,而char兄弟用來儲存定長字串,也就不知道大家怎麼能把我們兩兄弟給搞混呢?

char:varchar老哥,你說的對啊。我們兩雖然型別相似,都用來儲存字串,但是在儲存方式和檢索方式上都有差異。

varchar:並且我們在最大長度和是否保留尾部空格都不盡相同。(一片噓聲)

主持人:額額呢,以上兩位簡單闡述了你們的區別,不知道能否具體說明一下呢?

varchar:那我先來說說,我是varchar,我可以儲存長度為(0-65535位元組)的可變長度字串,這個長度同時也受限於資料庫或者資料表所使用的字符集(如果是utf-8,這裡可以指定的最大長度為21844,gbk則為32766),它可以占用更少的儲存空間。

我的儲存方式是:乙個或兩個位元組的長度字首+具體資料。

這裡乙個或兩個位元組的長度字首指的是:我會根據需要採用1個或者2個額外的位元組來記錄字串(具體資料)的長度。如果列的最大長度小於或者等於255位元組,則只使用1個位元組來表示,否則使用2個位元組。因為我的最大長度為65535,所以兩個位元組就足以表示我的資料的長度。

char:我是char,我能儲存(0-255位元組)的定長字串。舉個例子,char(10)可以儲存長度為10的定長字串,當長度不夠或者不滿10的時候,我會採取在尾部追加空格的方式讓所有的字串都達到指定的長度10,當長度大於10的時候,超過長度的值都不會儲存(如果執行在嚴格模式下,超過長度的值也不會儲存,但是會出現錯誤提示),這是我儲存資料的格式。當我檢索資料的時候,我會刪除所有的尾部空格(除非開啟 pad_char_to_full_length模式),而varchar老哥在檢索的時候則不會去除尾部空格。大家可以看看以下的測試:

mysql> create table char_test(char_col char(10));

mysql> insert into char_test(char_col)

-> values ('string1'),(' string2'),('string3 ');

mysql> select char_col,length(char_col) from char_test;

當檢索這些值的時候,會發現string3末尾的空格被去除了。

如果用varchar(10)字段儲存相同的值,可以得到如下結果:

這是我們兩乙個重要的區別。

上面varchar老哥說的也十分好,但是有一點我不能苟同,就是將字段定義為他占用的儲存空間更少。對於非常短的列來說,我比varchar老哥做的稍微好點,例如用char(1)來儲存只有y和n的值,採用我,就只需要乙個位元組,而varchar老哥卻需要兩個位元組,因為還有乙個記錄長度的位元組。還有,大家看看下面的資料:

value

char(4)storage required

varchar(4)storage required

'abcd''abcd'4 bytes

'abcd'5 bytes

'abc''abc '4 bytes

'abc'4 bytes

'ab''ab  '4 bytes

'ab'3 bytes

在表中第一行,此時varchar老哥還需要花費乙個位元組儲存自己有效資料的長度,而我不需要,此時應是我占用的儲存空間更少。第二行的資料顯示我們占用的儲存空間相等。在第三行,則是varchar老哥更勝一籌。

綜合上面三條記錄來看,所占用的空間都為12bytes,這裡是因為字串長度分布得十分均勻,那麼如果不均勻,也就是字串列的最大長度比平均長度大很多的時候,這時候varchar老哥就可以大展身手了。

varchar:看來char老弟對我的了解有點深刻啊(微微一笑),大家注意char老弟的這一句,在字串列的最大長度比平均長度大很多的時候,使用我比較好。為什麼要大很多呢?不是大2個位元組,相比之下,我的儲存空間就已經占用少了。

先來聽我說說:採用我,雖然說節省了儲存空間,但是由於行是變長的,在update的時候可能使行變得比原來更長,這就導致需要做許多額外的工作。如果乙個行占用的空間增長,並且在頁內沒有更多的空間可以儲存,在這種情況下,不同的儲存引擎處理方式是不一樣的。例如,myisam會將行拆分成不同的片段進行儲存,innodb則需要**頁來使行可以放進頁內。

在這種情況下,容易產生碎片,在這裡如果大家想使用我的話,得做一下折中。對於那種經常變更且字元長度比較接近的字元列使用char老弟還是更勝一籌,因為定長的char型別不容易產生碎片。

主持人:說了這麼多,不知道你們可以簡短概括或者說總結一下嗎?

總結

Varchar與char的區別

char 對英文 ascii 字元占用1個位元組,對乙個漢字占用2個位元組 varchar 的型別不以空格填滿,比如varchar 100 但它的值只是 qian 則它的值就是 qian 而char 不一樣,比如char 100 它的值是 qian 而實際上它在資料庫中是 qian qian後共有9...

varchar與char 的區別

char是一種固定長度的型別,varchar則是一種可變長度的型別,它們的區別是 char m 型別的資料列裡,每個值都占用m個位元組,如果某個長度小於m,mysql就會在它的右邊用空格字元補足 在檢索操作中那些填補出來的空格字元將被去掉 在varchar m 型別的資料列裡,每個值只占用剛好夠用的...

char與varchar的區別?

1 char m m代表可儲存的字元數,char儲存定長資料很方便,char欄位上的索引效率級高,比如定義char 10 那麼不論你儲存的資料是否達到了10個字元,都要占去10個字元的空間。2 varchar n n代表可儲存的位元組數,儲存變長資料,但儲存效率沒有char高。如果乙個字段可能的值是...