在MySQL下varchar類型最大長度是多少呢,我們百度查一下會發(fā)現(xiàn)varchar長度為varchar數(shù)據(jù)類型的長度支持到了65535,也就是說可以存放65532個字節(jié)的數(shù)據(jù)了,那到底是不是這樣的呢,我們來看看.
1、限制規(guī)則
字段的限制在字段定義的時候有以下規(guī)則:
a) 存儲限制:varchar 字段是將實際內(nèi)容單獨存儲在聚簇索引之外,內(nèi)容開頭用1到2個字節(jié)表示實際長度,長度超過255時需要2個字節(jié),因此最大長度不能超過65535.
b) 編碼長度限制:字符類型若為gbk,每個字符最多占2個字節(jié),最大長度不能超過32766;
字符類型若為utf8,每個字符最多占3個字節(jié),最大長度不能超過21845,若定義的時候超過上述限制,則varchar字段會被強行轉(zhuǎn)為text類型,并產(chǎn)生warning.
c) 行長度限制:導(dǎo)致實際應(yīng)用中varchar長度限制的是一個行定義的長度,MySQL要求一個行的定義長度不能超過65535,若定義的表長度超過這個值,則提示:
ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. You have to change some columns to TEXT or BLOBs。
2、計算例子,舉兩個例說明一下實際長度的計算.
a)若一個表只有一個varchar類型,如定義為:
create table t4(c varchar(N)) charset=gbk;
則此處N的最大值為(65535-1-2)/2= 32766,減1的原因是實際行存儲從第二個字節(jié)開始’;減2的原因是varchar頭部的2個字節(jié)表示長度;除2的原因是字符編碼是gbk.
b) 若一個表定義為:
create table t4(c int, c2 char(30), c3 varchar(N)) charset=utf8;
則此處N的最大值為 (65535-1-2-4-30*3)/3=21812,減1和減2與上例相同;減4的原因是int類型的c占4個字節(jié);減30*3的原因是char(30)占用90個字節(jié),編碼是utf8.
如果被varchar超過上述的b規(guī)則,被強轉(zhuǎn)成text類型,則每個字段占用定義長度為11字節(jié),當(dāng)然這已經(jīng)不是“varchar”了.
上網(wǎng)看了些資料,又在本地做了些實驗,原來vachar的最大長度真的是不定的,根據(jù)是否有非空字段來決定,在本地做了下實驗,innodb+latin的環(huán)境.
- -- success
- drop table if exists test;
- create table test(name varchar(65533) not null)engine=innodb DEFAULT CHARSET=latin1
- -- too large
- drop table if exists test;
create table test(name varchar(65533))engine=innodb DEFAULT CHARSET=latin1
對于第二種情況,允許空字段的時候是不能加到65533的長度的,最大只能到65532,到底應(yīng)該是引文的那種說法.
網(wǎng)上也有人做了類似的實驗,參考:http://stackoverflow.com/questions/8295131/best-practise-for-sql-varchar-column-length
- name varchar(100) not null will be 1 byte (length) + up to 100 chars (latin1)
- name varchar(500) not null will be 2 bytes (length) + up to 500 chars (latin1)
- name varchar(65533) not null will be 2 bytes (length) + up to 65533 chars (latin1)
- name varchar(65532) will be 2 bytes (length) + up to 65532 chars (latin1) + 1 null byte //Vevb.com
總結(jié)一下,原來mysql的vachar字段的類型雖然最大長度是65535,但是并不是能存這么多數(shù)據(jù),最大可以到65533,不允許非空字段的時候,當(dāng)允許非空字段的時候只能到65532.
2.CHAR(M), VARCHAR(M)不同之處
CHAR(M)定義的列的長度為固定的,M取值可以為0~255之間,當(dāng)保存CHAR值時,在它們的右邊填充空格以達到指定的長度。當(dāng)檢索到CHAR值時,尾部的空格被刪除掉。在存儲或檢索過程中不進行大小寫轉(zhuǎn)換。
CHAR存儲定長數(shù)據(jù)很方便,CHAR字段上的索引效率級高,比如定義char(10),那么不論你存儲的數(shù)據(jù)是否達到了10個字節(jié),都要占去10個字節(jié)的空間,不足的自動用空格填充。
VARCHAR(M)定義的列的長度為可變長字符串,M取值可以為0~65535之間,(VARCHAR的最大有效長度由最大行大小和使用的字符集確定。整體最大長度是65,532字節(jié))。VARCHAR值保存時只保存需要的字符數(shù),另加一個字節(jié)來記錄長度(如果列聲明的長度超過255,則使用兩個字節(jié))。
VARCHAR值保存時不進行填充。當(dāng)值保存和檢索時尾部的空格仍保留,符合標(biāo)準(zhǔn)SQL。varchar存儲變長數(shù)據(jù),但存儲效率沒有CHAR高。如果一個字段可能的值是不固定長度的,我們只知道它不可能超過10個字符,把它定義為 VARCHAR(10)是最合算的。VARCHAR類型的實際長度是它的值的實際長度+1。為什么"+1"呢?這一個字節(jié)用于保存實際使用了多大的長度。從空間上考慮,用varchar合適;從效率上考慮,用char合適,關(guān)鍵是根據(jù)實際情況找到權(quán)衡點。
如果被裁掉的字符不是空格,則會產(chǎn)生一條警告。如果裁剪非空格字符,則會造成錯誤(而不是警告)并通過使用嚴(yán)格SQL模式禁用值的插入。
3. VARCHAR和TEXT、BlOB類型的區(qū)別
VARCHAR,BLOB和TEXT類型是變長類型,對于其存儲需求取決于列值的實際長度(在前面的表格中用L表示),而不是取決于類型的最大可能尺寸。例如,一個VARCHAR(10)列能保存最大長度為10個字符的一個字符串,實際的存儲需要是字符串的長度 ,加上1個字節(jié)以記錄字符串的長度。對于字符串'abcd',L是4而存儲要求是5個字節(jié)。
BLOB和TEXT類型需要1,2,3或4個字節(jié)來記錄列值的長度,這取決于類型的最大可能長度。VARCHAR需要定義大小,有65535字節(jié)的最大限制;TEXT則不需要。如果你把一個超過列類型最大長度的值賦給一個BLOB或TEXT列,值被截斷以適合它。
一個BLOB是一個能保存可變數(shù)量的數(shù)據(jù)的二進制的大對象。4個BLOB類型TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB僅僅在他們能保存值的最大長度方面有所不同。
BLOB 可以儲存圖片,TEXT不行,TEXT只能儲存純文本文件。4個TEXT類型TINYTEXT、TEXT、MEDIUMTEXT和LONGTEXT對應(yīng)于4個BLOB類型,并且有同樣的最大長度和存儲需求。在BLOB和TEXT類型之間的唯一差別是對BLOB值的排序和比較以大小寫敏感方式執(zhí)行,而對TEXT值是大小寫不敏感的。換句話說,一個TEXT是一個大小寫不敏感的BLOB。
4.總結(jié)char,varchar,text區(qū)別
長度的區(qū)別,char范圍是0~255,varchar最長是64k,但是注意這里的64k是整個row的長度,要考慮到其它的column,還有如果存在not null的時候也會占用一位,對不同的字符集,有效長度還不一樣,比如utf8的,最多21845,還要除去別的column,但是varchar在一般情況下存儲都夠用了,如果遇到了大文本,考慮使用text,最大能到4G.
效率來說基本是char>varchar>text,但是如果使用的是Innodb引擎的話,推薦使用varchar代替char.
char和varchar可以有默認值,text不能指定默認值.
數(shù)據(jù)庫選擇合適的數(shù)據(jù)類型存儲還是很有必要的,對性能有一定影響,這里在零碎記錄兩筆,對于int類型的,如果不需要存取負值,最好加上unsigned,對于經(jīng)常出現(xiàn)在where語句中的字段,考慮加索引,整形的尤其適合加索引.
新聞熱點
疑難解答
圖片精選